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

Commit 304df463 authored by Pavel Maltsev's avatar Pavel Maltsev Committed by android-build-merger
Browse files

Merge "Remove dependency to libbinder in VHAL" into oc-dev

am: cff4cf89

Change-Id: I202512313e4843ae83aff0b894471b89a92a5e07
parents 6d60b794 cff4cf89
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ vhal_v2_0 = android.hardware.automotive.vehicle@2.0
include $(CLEAR_VARS)
LOCAL_MODULE := $(vhal_v2_0)-manager-lib
LOCAL_SRC_FILES := \
    common/src/AccessControlConfigParser.cpp \
    common/src/SubscriptionManager.cpp \
    common/src/VehicleHalManager.cpp \
    common/src/VehicleObjectPool.cpp \
@@ -35,7 +34,6 @@ LOCAL_EXPORT_C_INCLUDE_DIRS := \
    $(LOCAL_PATH)/common/include

LOCAL_SHARED_LIBRARIES := \
    libbinder \
    libhidlbase \
    libhidltransport \
    libhwbinder \
@@ -89,7 +87,6 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \

LOCAL_SHARED_LIBRARIES := \
    libbase \
    libbinder \
    libhidlbase \
    libhidltransport \
    libhwbinder \
@@ -117,7 +114,6 @@ LOCAL_WHOLE_STATIC_LIBRARIES := \
    $(vhal_v2_0)-manager-lib \

LOCAL_SRC_FILES:= \
    tests/AccessControlConfigParser_test.cpp \
    tests/RecurrentTimer_test.cpp \
    tests/SubscriptionManager_test.cpp \
    tests/VehicleHalManager_test.cpp \
@@ -125,7 +121,6 @@ LOCAL_SRC_FILES:= \
    tests/VehiclePropConfigIndex_test.cpp \

LOCAL_SHARED_LIBRARIES := \
    libbinder \
    libhidlbase \
    libhidltransport \
    libhwbinder \
@@ -153,7 +148,6 @@ LOCAL_SRC_FILES := \

LOCAL_SHARED_LIBRARIES := \
    libbase \
    libbinder \
    libhidlbase \
    libhidltransport \
    libhwbinder \
+0 −113
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.
 */

#ifndef android_hardware_automotive_vehicle_V2_0_AccessControlConfigParser_H_
#define android_hardware_automotive_vehicle_V2_0_AccessControlConfigParser_H_

#include <string>
#include <vector>
#include <unordered_map>
#include <list>

#include <android/hardware/automotive/vehicle/2.0/types.h>

namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
namespace V2_0 {

struct PropertyAcl {
    int32_t propId;
    unsigned uid;
    VehiclePropertyAccess access;
};

using PropertyAclMap = std::unordered_multimap<int32_t, PropertyAcl>;

/**
 * Parser for per-property access control in vehicle HAL.
 *
 * It supports the following format:
 *   Set ALIAS_NAME UID
 *   {S,V}:0x0305   {ALIAS_NAME,UID}   {R,W,RW}
 *
 * ALIAS_NAME is just an alias for UID
 * S - for system properties (VehiclePropertyGroup::SYSTEM)
 * V - for vendor properties (VehiclePropertyGroup::VENDOR)
 *
 * Example:
 *
 *   Set AID_AUDIO  1004
 *   Set AID_MY_APP     10022
 *
 *   S:0x0305   AID_AUDIO   RW
 *   S:0x0305   10021       R
 *   V:0x0101   AID_MY_APP  R
 */
class AccessControlConfigParser {
public:
    /**
     * Creates an instance of AccessControlConfigParser
     *
     * @param properties - properties supported by HAL implementation
     */
    AccessControlConfigParser(const std::vector<int32_t>& properties);

    /**
     * Parses config content from given stream and writes results to
     * propertyAclMap.
     */
    bool parseFromStream(std::istream* stream, PropertyAclMap* propertyAclMap);

private:
    bool processTokens(std::list<std::string>* tokens,
                       PropertyAclMap* propertyAclMap);

    bool parsePropertyGroup(char group,
                            VehiclePropertyGroup* outPropertyGroup) const;

    bool parsePropertyId(const std::string& strPropId,
                                VehiclePropertyGroup propertyGroup,
                                int32_t* outVehicleProperty) const;

    bool parseUid(const std::string& strUid, unsigned* outUid) const;

    bool parseAccess(const std::string& strAccess,
                     VehiclePropertyAccess* outAccess) const;


    std::string readNextToken(std::list<std::string>* tokens) const;

    static bool parseInt(const char* strValue, int* outIntValue);
    static void split(const std::string& line,
                      std::list<std::string>* outTokens);

private:
    std::unordered_map<std::string, unsigned> mUidMap {};  // Contains UID
    // aliases.

    // Map property ids w/o TYPE and AREA to VehicleProperty.
    std::unordered_map<int32_t, int32_t> mStrippedToVehiclePropertyMap;
};

}  // namespace V2_0
}  // namespace vehicle
}  // namespace automotive
}  // namespace hardware
}  // namespace android

#endif // android_hardware_automotive_vehicle_V2_0_AccessControlConfigParser_H_
+3 −7
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@

#include <android/log.h>
#include <hidl/HidlSupport.h>
#include <hwbinder/IPCThreadState.h>
#include <utils/SortedVector.h>

#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>

@@ -39,10 +39,8 @@ namespace V2_0 {

class HalClient : public android::RefBase {
public:
    HalClient(const sp<IVehicleCallback> &callback,
              int32_t pid,
              int32_t uid)
        : mCallback(callback), mPid(pid), mUid(uid) {}
    HalClient(const sp<IVehicleCallback> &callback)
        : mCallback(callback) {}

    virtual ~HalClient() {}
public:
@@ -56,8 +54,6 @@ public:

private:
    const sp<IVehicleCallback> mCallback;
    const int32_t mPid;
    const int32_t mUid;

    std::map<int32_t, SubscribeOptions> mSubscriptions;
};
+2 −22
Original line number Diff line number Diff line
@@ -27,9 +27,7 @@
#include <set>

#include <android/hardware/automotive/vehicle/2.0/IVehicle.h>
#include <hwbinder/IPCThreadState.h>

#include "AccessControlConfigParser.h"
#include "ConcurrentQueue.h"
#include "SubscriptionManager.h"
#include "VehicleHal.h"
@@ -42,11 +40,6 @@ namespace automotive {
namespace vehicle {
namespace V2_0 {

struct Caller {
    pid_t pid;
    uid_t uid;
};

/**
 * This class is a thick proxy between IVehicle HIDL interface and vendor's implementation.
 *
@@ -99,14 +92,8 @@ private:

    const VehiclePropConfig* getPropConfigOrNull(int32_t prop) const;

    bool checkWritePermission(const VehiclePropConfig &config,
                              const Caller& callee) const;
    bool checkReadPermission(const VehiclePropConfig &config,
                             const Caller& caller) const;
    bool checkAcl(uid_t callerUid,
                  int32_t propertyId,
                  VehiclePropertyAccess requiredAccess) const;

    bool checkWritePermission(const VehiclePropConfig &config) const;
    bool checkReadPermission(const VehiclePropConfig &config) const;
    void onAllClientsUnsubscribed(int32_t propertyId);

    static bool isSubscribable(const VehiclePropConfig& config,
@@ -114,12 +101,6 @@ private:
    static bool isSampleRateFixed(VehiclePropertyChangeMode mode);
    static float checkSampleRate(const VehiclePropConfig& config,
                                 float sampleRate);
    static void readAndParseAclConfig(const char* filename,
                                      AccessControlConfigParser* parser,
                                      PropertyAclMap* outAclMap);

    static Caller getCaller();

private:
    VehicleHal* mHal;
    std::unique_ptr<VehiclePropConfigIndex> mConfigIndex;
@@ -130,7 +111,6 @@ private:
    ConcurrentQueue<VehiclePropValuePtr> mEventQueue;
    BatchingConsumer<VehiclePropValuePtr> mBatchingConsumer;
    VehiclePropValuePool mValueObjectPool;
    PropertyAclMap mPropertyAclMap;
};

}  // namespace V2_0
+0 −228
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 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.
 */

#define LOG_TAG "automotive.vehicle@2.0-impl"

#include "AccessControlConfigParser.h"
#include "VehicleUtils.h"

#include <fstream>
#include <iostream>
#include <sstream>

#include <log/log.h>

namespace android {
namespace hardware {
namespace automotive {
namespace vehicle {
namespace V2_0 {

AccessControlConfigParser::AccessControlConfigParser(
        const std::vector<int32_t>& properties) {
    // Property Id in the config file doesn't include information about
    // type and area. So we want to create a map from these kind of
    // *stripped* properties to the whole VehicleProperty.
    // We also want to filter out ACL to the properties that supported
    // by concrete Vehicle HAL implementation.
    for (auto prop : properties) {
        auto strippedProp = prop
                            & ~toInt(VehiclePropertyType::MASK)
                            & ~toInt(VehicleArea::MASK);
        mStrippedToVehiclePropertyMap.emplace(strippedProp, prop);
    }
}

bool AccessControlConfigParser::parseFromStream(
        std::istream* stream, PropertyAclMap* propertyAclMap) {
    std::list<std::string> tokens;
    std::string line;
    int lineNo = 0;
    bool warnings = false;
    for (;std::getline(*stream, line); lineNo++) {
        split(line, &tokens);
        if (!processTokens(&tokens, propertyAclMap)) {
            warnings = true;
            ALOGW("Failed to parse line %d : %s", lineNo, line.c_str());
        }
    }
    return !warnings;
}


bool AccessControlConfigParser::processTokens(std::list<std::string>* tokens,
                                              PropertyAclMap* propertyAclMap) {
    std::string token = readNextToken(tokens);
    if (token.empty() || token[0] == '#') {   // Ignore comment.
        return true;
    }

    if (token == "Set") {
        std::string alias = readNextToken(tokens);
        std::string strUid = readNextToken(tokens);
        if (alias.empty() || strUid.empty()) {
            ALOGW("Expected alias and UID must be specified");
            return false;
        }
        int uid;
        if (!parseInt(strUid.c_str(), &uid)) {
            ALOGW("Invalid UID: %d", uid);
        }
        mUidMap.emplace(std::move(alias), uid);
    } else if (token.size() > 2 && token[1] == ':') {
        VehiclePropertyGroup propGroup;
        if (!parsePropertyGroup(token[0], &propGroup)) {
            return false;
        }
        std::string strUid = readNextToken(tokens);
        std::string strAccess = readNextToken(tokens);
        if (strUid.empty() || strAccess.empty()) {
            ALOGW("Expected UID and access for property: %s",
                  token.c_str());
        }


        PropertyAcl acl;
        if (parsePropertyId(token.substr(2), propGroup, &acl.propId)
            && parseUid(strUid, &acl.uid)
            && parseAccess(strAccess, &acl.access)) {
            propertyAclMap->emplace(acl.propId, std::move(acl));
        } else {
            return false;
        }
    } else {
        ALOGW("Unexpected token: %s", token.c_str());
        return false;
    }

    return true;
}

bool AccessControlConfigParser::parsePropertyGroup(
        char group, VehiclePropertyGroup* outPropertyGroup) const {
    switch (group) {
        case 'S':  // Fall through.
        case 's':
            *outPropertyGroup = VehiclePropertyGroup::SYSTEM;
            break;
        case 'V':  // Fall through.
        case 'v':
            *outPropertyGroup = VehiclePropertyGroup::VENDOR;
            break;
        default:
            ALOGW("Unexpected group: %c", group);
            return false;
    }
    return true;
}

bool AccessControlConfigParser::parsePropertyId(
        const std::string& strPropId,
        VehiclePropertyGroup propertyGroup,
        int32_t* outVehicleProperty) const {
    int32_t propId;
    if (!parseInt(strPropId.c_str(), &propId)) {
        ALOGW("Failed to convert property id to integer: %s",
              strPropId.c_str());
        return false;
    }
    propId |= static_cast<int>(propertyGroup);
    auto it = mStrippedToVehiclePropertyMap.find(propId);
    if (it == mStrippedToVehiclePropertyMap.end()) {
        ALOGW("Property Id not found or not supported: 0x%x", propId);
        return false;
    }
    *outVehicleProperty = it->second;
    return true;
}

bool AccessControlConfigParser::parseInt(const char* strValue,
                                         int* outIntValue) {
    char* end;
    long num = std::strtol(strValue, &end, 0 /* auto detect base */);
    bool success = *end == 0 && errno != ERANGE;
    if (success) {
        *outIntValue = static_cast<int>(num);
    }

    return success;
}

bool AccessControlConfigParser::parseUid(const std::string& strUid,
                                         unsigned* outUid) const {
    auto element = mUidMap.find(strUid);
    if (element != mUidMap.end()) {
        *outUid = element->second;
    } else {
        int val;
        if (!parseInt(strUid.c_str(), &val)) {
            ALOGW("Failed to convert UID '%s' to integer", strUid.c_str());
            return false;
        }
        *outUid = static_cast<unsigned>(val);
    }
    return true;
}

bool AccessControlConfigParser::parseAccess(
        const std::string& strAccess, VehiclePropertyAccess* outAccess) const {
    if (strAccess.size() == 0 || strAccess.size() > 2) {
        ALOGW("Unknown access mode '%s'", strAccess.c_str());
        return false;
    }
    int32_t access = static_cast<int32_t>(VehiclePropertyAccess::NONE);
    for (char c : strAccess) {
        if (c == 'R' || c == 'r') {
            access |= VehiclePropertyAccess::READ;
        } else if (c == 'W' || c == 'w') {
            access |= VehiclePropertyAccess::WRITE;
        } else {
            ALOGW("Unknown access mode: %c", c);
            return false;
        }
    }
    *outAccess = static_cast<VehiclePropertyAccess>(access);
    return true;
}

void AccessControlConfigParser::split(const std::string& line,
                                      std::list<std::string>* outTokens) {
    outTokens->clear();
    std::istringstream iss(line);

    while (!iss.eof()) {
        std::string token;
        iss >> token;
        outTokens->push_back(std::move(token));
    }
}

std::string AccessControlConfigParser::readNextToken(
        std::list<std::string>* tokens) const {
    if (tokens->empty()) {
        return "";
    }

    std::string token = tokens->front();
    tokens->pop_front();
    return token;
}

}  // namespace V2_0
}  // namespace vehicle
}  // namespace automotive
}  // namespace hardware
}  // namespace android
Loading