Loading libs/ui/DeviceProductInfo.cpp +20 −15 Original line number Diff line number Diff line Loading @@ -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 libs/ui/DisplayInfo.cpp +16 −16 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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 libs/ui/include/ui/DeviceProductInfo.h +6 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <string> #include <type_traits> #include <variant> #include <vector> #include <utils/Flattenable.h> Loading Loading @@ -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; Loading libs/ui/include_private/ui/FlattenableHelpers.h +109 −22 Original line number Diff line number Diff line Loading @@ -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 libs/ui/tests/Android.bp +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
libs/ui/DeviceProductInfo.cpp +20 −15 Original line number Diff line number Diff line Loading @@ -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
libs/ui/DisplayInfo.cpp +16 −16 Original line number Diff line number Diff line Loading @@ -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); } Loading @@ -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
libs/ui/include/ui/DeviceProductInfo.h +6 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <string> #include <type_traits> #include <variant> #include <vector> #include <utils/Flattenable.h> Loading Loading @@ -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; Loading
libs/ui/include_private/ui/FlattenableHelpers.h +109 −22 Original line number Diff line number Diff line Loading @@ -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
libs/ui/tests/Android.bp +7 −0 Original line number Diff line number Diff line Loading @@ -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