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

Commit 896e6305 authored by Marin Shalamanov's avatar Marin Shalamanov
Browse files

Add relative address to DeviceProductInfo.

This CL adds a field relativeAddress to DeviceProductInfo so it can
be surfaced in the framework. For HDMI connections the field is
populated with the physical address. This CL also adds helper
functions for serializing to Flattenable and enhances the
serialization security.

Bug: 147994746
Bug: 153589294
Test: atest DisplayIdentificationTest
Change-Id: I2711407aa1be079df8086e233ee3f0cf90ba1741
parent 3000b08d
Loading
Loading
Loading
Loading
+20 −15
Original line number Diff line number Diff line
@@ -18,33 +18,38 @@

#include <ui/FlattenableHelpers.h>

#define RETURN_IF_ERROR(op) \
    if (const status_t status = (op); status != OK) return status;

namespace android {

size_t DeviceProductInfo::getFlattenedSize() const {
    return FlattenableHelpers::getFlattenedSize(name) + sizeof(manufacturerPnpId) +
            FlattenableHelpers::getFlattenedSize(productId) + sizeof(manufactureOrModelDate);
    return FlattenableHelpers::getFlattenedSize(name) +
            FlattenableHelpers::getFlattenedSize(manufacturerPnpId) +
            FlattenableHelpers::getFlattenedSize(productId) +
            FlattenableHelpers::getFlattenedSize(manufactureOrModelDate) +
            FlattenableHelpers::getFlattenedSize(relativeAddress);
}

status_t DeviceProductInfo::flatten(void* buffer, size_t size) const {
    if (size < getFlattenedSize()) {
        return NO_MEMORY;
    }
    FlattenableHelpers::write(buffer, size, name);
    FlattenableUtils::write(buffer, size, manufacturerPnpId);
    FlattenableHelpers::write(buffer, size, productId);
    FlattenableUtils::write(buffer, size, manufactureOrModelDate);
    return NO_ERROR;
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, name));
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, manufacturerPnpId));
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, productId));
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, manufactureOrModelDate));
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, relativeAddress));
    return OK;
}

status_t DeviceProductInfo::unflatten(void const* buffer, size_t size) {
    if (size < getFlattenedSize()) {
        return NO_MEMORY;
    }
    FlattenableHelpers::read(buffer, size, &name);
    FlattenableUtils::read(buffer, size, manufacturerPnpId);
    FlattenableHelpers::read(buffer, size, &productId);
    FlattenableUtils::read(buffer, size, manufactureOrModelDate);
    return NO_ERROR;
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &name));
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &manufacturerPnpId));
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &productId));
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &manufactureOrModelDate));
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &relativeAddress));
    return OK;
}

} // namespace android
+16 −16
Original line number Diff line number Diff line
@@ -20,10 +20,15 @@

#include <ui/FlattenableHelpers.h>

#define RETURN_IF_ERROR(op) \
    if (const status_t status = (op); status != OK) return status;

namespace android {

size_t DisplayInfo::getFlattenedSize() const {
    return sizeof(connectionType) + sizeof(density) + sizeof(secure) +
    return FlattenableHelpers::getFlattenedSize(connectionType) +
            FlattenableHelpers::getFlattenedSize(density) +
            FlattenableHelpers::getFlattenedSize(secure) +
            FlattenableHelpers::getFlattenedSize(deviceProductInfo);
}

@@ -31,24 +36,19 @@ status_t DisplayInfo::flatten(void* buffer, size_t size) const {
    if (size < getFlattenedSize()) {
        return NO_MEMORY;
    }
    FlattenableUtils::write(buffer, size, connectionType);
    FlattenableUtils::write(buffer, size, density);
    FlattenableUtils::write(buffer, size, secure);
    FlattenableHelpers::write(buffer, size, deviceProductInfo);

    return NO_ERROR;
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, connectionType));
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, density));
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, secure));
    RETURN_IF_ERROR(FlattenableHelpers::flatten(&buffer, &size, deviceProductInfo));
    return OK;
}

status_t DisplayInfo::unflatten(void const* buffer, size_t size) {
    if (size < getFlattenedSize()) {
        return NO_MEMORY;
    }
    FlattenableUtils::read(buffer, size, connectionType);
    FlattenableUtils::read(buffer, size, density);
    FlattenableUtils::read(buffer, size, secure);
    FlattenableHelpers::read(buffer, size, &deviceProductInfo);

    return NO_ERROR;
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &connectionType));
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &density));
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &secure));
    RETURN_IF_ERROR(FlattenableHelpers::unflatten(&buffer, &size, &deviceProductInfo));
    return OK;
}

} // namespace android
+6 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <string>
#include <type_traits>
#include <variant>
#include <vector>

#include <utils/Flattenable.h>

@@ -58,6 +59,11 @@ struct DeviceProductInfo : LightFlattenable<DeviceProductInfo> {
    static_assert(std::is_trivially_copyable_v<ManufactureOrModelDate>);
    ManufactureOrModelDate manufactureOrModelDate;

    // Relative address in the display network. Empty vector indicates that the
    // address is unavailable.
    // For example, for HDMI connected device this will be the physical address.
    std::vector<uint8_t> relativeAddress;

    bool isFixedSize() const { return false; }
    size_t getFlattenedSize() const;
    status_t flatten(void* buffer, size_t size) const;
+109 −22
Original line number Diff line number Diff line
@@ -16,56 +16,143 @@

#pragma once

#include <numeric>
#include <optional>
#include <type_traits>
#include <vector>

#include <utils/Flattenable.h>

#define RETURN_IF_ERROR(op) \
    if (const status_t status = (op); status != OK) return status;

namespace android {

struct FlattenableHelpers {
    // Flattenable helpers for reading and writing std::string
    static size_t getFlattenedSize(const std::string& str) { return str.length() + 1; }
    // Helpers for reading and writing POD structures
    template <class T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
    static constexpr size_t getFlattenedSize(const T&) {
        return sizeof(T);
    }

    template <class T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
    static status_t flatten(void** buffer, size_t* size, const T& value) {
        if (*size < sizeof(T)) return NO_MEMORY;
        FlattenableUtils::write(*buffer, *size, value);
        return OK;
    }

    template <class T, typename = std::enable_if_t<std::is_trivially_copyable_v<T>>>
    static status_t unflatten(const void** buffer, size_t* size, T* value) {
        if (*size < sizeof(T)) return NO_MEMORY;
        FlattenableUtils::read(*buffer, *size, *value);
        return OK;
    }

    // Helpers for reading and writing std::string
    static size_t getFlattenedSize(const std::string& str) { return sizeof(size_t) + str.length(); }

    static status_t flatten(void** buffer, size_t* size, const std::string& str) {
        if (*size < getFlattenedSize(str)) return NO_MEMORY;
        flatten(buffer, size, str.length());
        memcpy(reinterpret_cast<char*>(*buffer), str.c_str(), str.length());
        FlattenableUtils::advance(*buffer, *size, str.length());
        return OK;
    }

    static status_t unflatten(const void** buffer, size_t* size, std::string* str) {
        size_t length;
        RETURN_IF_ERROR(unflatten(buffer, size, &length));
        if (*size < length) return NO_MEMORY;
        str->assign(reinterpret_cast<const char*>(*buffer), length);
        FlattenableUtils::advance(*buffer, *size, length);
        return OK;
    }

    static void write(void*& buffer, size_t& size, const std::string& str) {
        strcpy(reinterpret_cast<char*>(buffer), str.c_str());
        FlattenableUtils::advance(buffer, size, getFlattenedSize(str));
    // Helpers for reading and writing LightFlattenable
    template <class T>
    static size_t getFlattenedSize(const LightFlattenable<T>& value) {
        return value.getFlattenedSize();
    }

    static void read(void const*& buffer, size_t& size, std::string* str) {
        str->assign(reinterpret_cast<const char*>(buffer));
        FlattenableUtils::advance(buffer, size, getFlattenedSize(*str));
    template <class T>
    static status_t flatten(void** buffer, size_t* size, const LightFlattenable<T>& value) {
        RETURN_IF_ERROR(value.flatten(*buffer, *size));
        FlattenableUtils::advance(*buffer, *size, value.getFlattenedSize());
        return OK;
    }

    // Flattenable utils for reading and writing std::optional
    template <class T, typename = std::enable_if_t<std::is_base_of_v<LightFlattenable<T>, T>>>
    template <class T>
    static status_t unflatten(const void** buffer, size_t* size, LightFlattenable<T>* value) {
        RETURN_IF_ERROR(value->unflatten(*buffer, *size));
        FlattenableUtils::advance(*buffer, *size, value->getFlattenedSize());
        return OK;
    }

    // Helpers for reading and writing std::optional
    template <class T, typename = std::enable_if_t<std::negation_v<std::is_trivially_copyable<T>>>>
    static size_t getFlattenedSize(const std::optional<T>& value) {
        return sizeof(bool) + (value ? value->getFlattenedSize() : 0);
        return sizeof(bool) + (value ? getFlattenedSize(*value) : 0);
    }

    template <class T, typename = std::enable_if_t<std::is_base_of_v<LightFlattenable<T>, T>>>
    static void write(void*& buffer, size_t& size, const std::optional<T>& value) {
    template <class T, typename = std::enable_if_t<std::negation_v<std::is_trivially_copyable<T>>>>
    static status_t flatten(void** buffer, size_t* size, const std::optional<T>& value) {
        if (value) {
            FlattenableUtils::write(buffer, size, true);
            value->flatten(buffer, size);
            FlattenableUtils::advance(buffer, size, value->getFlattenedSize());
            RETURN_IF_ERROR(flatten(buffer, size, true));
            RETURN_IF_ERROR(flatten(buffer, size, *value));
        } else {
            FlattenableUtils::write(buffer, size, false);
            RETURN_IF_ERROR(flatten(buffer, size, false));
        }
        return OK;
    }

    template <class T, typename = std::enable_if_t<std::is_base_of_v<LightFlattenable<T>, T>>>
    static void read(void const*& buffer, size_t& size, std::optional<T>* value) {
    template <class T, typename = std::enable_if_t<std::negation_v<std::is_trivially_copyable<T>>>>
    static status_t unflatten(const void** buffer, size_t* size, std::optional<T>* value) {
        bool isPresent;
        FlattenableUtils::read(buffer, size, isPresent);
        RETURN_IF_ERROR(unflatten(buffer, size, &isPresent));
        if (isPresent) {
            *value = T();
            (*value)->unflatten(buffer, size);
            FlattenableUtils::advance(buffer, size, (*value)->getFlattenedSize());
            RETURN_IF_ERROR(unflatten(buffer, size, &(**value)));
        } else {
            value->reset();
        }
        return OK;
    }

    // Helpers for reading and writing std::vector
    template <class T>
    static size_t getFlattenedSize(const std::vector<T>& value) {
        return std::accumulate(value.begin(), value.end(), sizeof(size_t),
                               [](size_t sum, const T& element) {
                                   return sum + getFlattenedSize(element);
                               });
    }

    template <class T>
    static status_t flatten(void** buffer, size_t* size, const std::vector<T>& value) {
        RETURN_IF_ERROR(flatten(buffer, size, value.size()));
        for (const auto& element : value) {
            RETURN_IF_ERROR(flatten(buffer, size, element));
        }
        return OK;
    }

    template <class T>
    static status_t unflatten(const void** buffer, size_t* size, std::vector<T>* value) {
        size_t numElements;
        RETURN_IF_ERROR(unflatten(buffer, size, &numElements));
        // We don't need an extra size check since each iteration of the loop does that
        std::vector<T> elements;
        for (size_t i = 0; i < numElements; i++) {
            T element;
            RETURN_IF_ERROR(unflatten(buffer, size, &element));
            elements.push_back(element);
        }
        *value = std::move(elements);
        return OK;
    }
};

} // namespace android

#undef RETURN_IF_ERROR
 No newline at end of file
+7 −0
Original line number Diff line number Diff line
@@ -28,6 +28,13 @@ cc_test {
    cflags: ["-Wall", "-Werror"],
}

cc_test {
    name: "FlattenableHelpers_test",
    shared_libs: ["libui"],
    srcs: ["FlattenableHelpers_test.cpp"],
    cflags: ["-Wall", "-Werror"],
}

cc_test {
    name: "GraphicBufferAllocator_test",
    header_libs: [
Loading