diff options
author | 2020-02-17 17:03:07 +0100 | |
---|---|---|
committer | 2020-03-18 14:01:39 +0100 | |
commit | 359a7e7805d6123c930094c5c47dacc0f01a23a4 (patch) | |
tree | 72d6ac70b2ac0c4fa915a01fdb82af2af0310df5 | |
parent | 1581d90eca506a0979c4146667fbfc4022381c07 (diff) |
Use std::string in DeviceProductInfo and serialize it as Flattenable
Use std::string instead of fixed size char arrays. Serialize
DeviceProductInfo and DisplayInfo as Flattenable instead of using
memcpy().
Bug: 145299597
Test: 1. m
2. adb shell dumpsys display
3. check that DeviceProductInfo is correctly populated
Change-Id: Id21186138b39d7bb167c41ff7ee9387081ac6285
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 12 | ||||
-rw-r--r-- | libs/ui/Android.bp | 4 | ||||
-rw-r--r-- | libs/ui/DeviceProductInfo.cpp | 50 | ||||
-rw-r--r-- | libs/ui/DisplayInfo.cpp | 54 | ||||
-rw-r--r-- | libs/ui/include/ui/DeviceProductInfo.h | 18 | ||||
-rw-r--r-- | libs/ui/include/ui/DisplayInfo.h | 10 | ||||
-rw-r--r-- | libs/ui/include_private/ui/FlattenableHelpers.h | 71 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp | 9 | ||||
-rw-r--r-- | services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp | 24 |
9 files changed, 216 insertions, 36 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index 04c21a9e1d..e1c112aaed 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -371,10 +371,8 @@ public: data.writeStrongBinder(display); remote()->transact(BnSurfaceComposer::GET_DISPLAY_INFO, data, &reply); const status_t result = reply.readInt32(); - if (result == NO_ERROR) { - memcpy(info, reply.readInplace(sizeof(DisplayInfo)), sizeof(DisplayInfo)); - } - return result; + if (result != NO_ERROR) return result; + return reply.read(*info); } virtual status_t getDisplayConfigs(const sp<IBinder>& display, Vector<DisplayConfig>* configs) { @@ -1377,10 +1375,8 @@ status_t BnSurfaceComposer::onTransact( const sp<IBinder> display = data.readStrongBinder(); const status_t result = getDisplayInfo(display, &info); reply->writeInt32(result); - if (result == NO_ERROR) { - memcpy(reply->writeInplace(sizeof(DisplayInfo)), &info, sizeof(DisplayInfo)); - } - return NO_ERROR; + if (result != NO_ERROR) return result; + return reply->write(info); } case GET_DISPLAY_CONFIGS: { CHECK_INTERFACE(ISurfaceComposer, data, reply); diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp index 9f7f36f848..3965cf0025 100644 --- a/libs/ui/Android.bp +++ b/libs/ui/Android.bp @@ -46,7 +46,7 @@ cc_library_static { apex_available: [ "//apex_available:anyapex", - "//apex_available:platform", + "//apex_available:platform", ], shared_libs: [ "libutils", @@ -97,6 +97,8 @@ cc_library_shared { "BufferHubEventFd.cpp", "BufferHubMetadata.cpp", "DebugUtils.cpp", + "DeviceProductInfo.cpp", + "DisplayInfo.cpp", "Fence.cpp", "FenceTime.cpp", "FrameStats.cpp", diff --git a/libs/ui/DeviceProductInfo.cpp b/libs/ui/DeviceProductInfo.cpp new file mode 100644 index 0000000000..efd61b6111 --- /dev/null +++ b/libs/ui/DeviceProductInfo.cpp @@ -0,0 +1,50 @@ +/* + * Copyright 2020 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. + */ + +#include <ui/DeviceProductInfo.h> + +#include <ui/FlattenableHelpers.h> + +namespace android { + +size_t DeviceProductInfo::getFlattenedSize() const { + return FlattenableHelpers::getFlattenedSize(name) + sizeof(manufacturerPnpId) + + FlattenableHelpers::getFlattenedSize(productId) + sizeof(manufactureOrModelDate); +} + +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; +} + +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; +} + +} // namespace android diff --git a/libs/ui/DisplayInfo.cpp b/libs/ui/DisplayInfo.cpp new file mode 100644 index 0000000000..6ed7e19690 --- /dev/null +++ b/libs/ui/DisplayInfo.cpp @@ -0,0 +1,54 @@ +/* + * Copyright 2020 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. + */ + +#include <ui/DisplayInfo.h> + +#include <cstdint> + +#include <ui/FlattenableHelpers.h> + +namespace android { + +size_t DisplayInfo::getFlattenedSize() const { + return sizeof(connectionType) + sizeof(density) + sizeof(secure) + + FlattenableHelpers::getFlattenedSize(deviceProductInfo); +} + +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; +} + +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; +} + +} // namespace android diff --git a/libs/ui/include/ui/DeviceProductInfo.h b/libs/ui/include/ui/DeviceProductInfo.h index c396e738b9..cc5ebe4311 100644 --- a/libs/ui/include/ui/DeviceProductInfo.h +++ b/libs/ui/include/ui/DeviceProductInfo.h @@ -19,8 +19,12 @@ #include <array> #include <cstdint> #include <optional> +#include <string> +#include <type_traits> #include <variant> +#include <utils/Flattenable.h> + namespace android { // NUL-terminated plug and play ID. @@ -29,9 +33,7 @@ using PnpId = std::array<char, 4>; // Product-specific information about the display or the directly connected device on the // display chain. For example, if the display is transitively connected, this field may contain // product information about the intermediate device. -struct DeviceProductInfo { - static constexpr size_t TEXT_BUFFER_SIZE = 20; - +struct DeviceProductInfo : LightFlattenable<DeviceProductInfo> { struct ModelYear { uint32_t year; }; @@ -44,16 +46,22 @@ struct DeviceProductInfo { }; // Display name. - std::array<char, TEXT_BUFFER_SIZE> name; + std::string name; // Manufacturer Plug and Play ID. PnpId manufacturerPnpId; // Manufacturer product ID. - std::array<char, TEXT_BUFFER_SIZE> productId; + std::string productId; using ManufactureOrModelDate = std::variant<ModelYear, ManufactureYear, ManufactureWeekAndYear>; + static_assert(std::is_trivially_copyable_v<ManufactureOrModelDate>); ManufactureOrModelDate manufactureOrModelDate; + + bool isFixedSize() const { return false; } + size_t getFlattenedSize() const; + status_t flatten(void* buffer, size_t size) const; + status_t unflatten(void const* buffer, size_t size); }; } // namespace android diff --git a/libs/ui/include/ui/DisplayInfo.h b/libs/ui/include/ui/DisplayInfo.h index 897060c2ed..03e0a3886e 100644 --- a/libs/ui/include/ui/DisplayInfo.h +++ b/libs/ui/include/ui/DisplayInfo.h @@ -20,19 +20,23 @@ #include <type_traits> #include <ui/DeviceProductInfo.h> +#include <utils/Flattenable.h> namespace android { enum class DisplayConnectionType { Internal, External }; // Immutable information about physical display. -struct DisplayInfo { +struct DisplayInfo : LightFlattenable<DisplayInfo> { DisplayConnectionType connectionType = DisplayConnectionType::Internal; float density = 0.f; bool secure = false; std::optional<DeviceProductInfo> deviceProductInfo; -}; -static_assert(std::is_trivially_copyable_v<DisplayInfo>); + bool isFixedSize() const { return false; } + size_t getFlattenedSize() const; + status_t flatten(void* buffer, size_t size) const; + status_t unflatten(void const* buffer, size_t size); +}; } // namespace android diff --git a/libs/ui/include_private/ui/FlattenableHelpers.h b/libs/ui/include_private/ui/FlattenableHelpers.h new file mode 100644 index 0000000000..bdf480478a --- /dev/null +++ b/libs/ui/include_private/ui/FlattenableHelpers.h @@ -0,0 +1,71 @@ +/* + * Copyright 2020 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. + */ + +#pragma once + +#include <optional> +#include <type_traits> + +#include <utils/Flattenable.h> + +namespace android { + +struct FlattenableHelpers { + // Flattenable helpers for reading and writing std::string + static size_t getFlattenedSize(const std::string& str) { return str.length() + 1; } + + 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)); + } + + 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)); + } + + // Flattenable utils for reading and writing std::optional + template <class T, typename = std::enable_if_t<std::is_base_of_v<LightFlattenable<T>, T>>> + static size_t getFlattenedSize(const std::optional<T>& value) { + return sizeof(bool) + (value ? value->getFlattenedSize() : 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) { + if (value) { + FlattenableUtils::write(buffer, size, true); + value->flatten(buffer, size); + FlattenableUtils::advance(buffer, size, value->getFlattenedSize()); + } else { + FlattenableUtils::write(buffer, size, false); + } + } + + 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) { + bool isPresent; + FlattenableUtils::read(buffer, size, isPresent); + if (isPresent) { + *value = T(); + (*value)->unflatten(buffer, size); + FlattenableUtils::advance(buffer, size, (*value)->getFlattenedSize()); + } else { + value->reset(); + } + } +}; + +} // namespace android diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp b/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp index f24f3142f1..63897cc102 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp +++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp @@ -70,12 +70,8 @@ char getPnpLetter(uint16_t id) { DeviceProductInfo buildDeviceProductInfo(const Edid& edid) { DeviceProductInfo info; - std::copy(edid.displayName.begin(), edid.displayName.end(), info.name.begin()); - info.name[edid.displayName.size()] = '\0'; - - const auto productId = std::to_string(edid.productId); - std::copy(productId.begin(), productId.end(), info.productId.begin()); - info.productId[productId.size()] = '\0'; + info.name.assign(edid.displayName); + info.productId = std::to_string(edid.productId); info.manufacturerPnpId = edid.pnpId; constexpr uint8_t kModelYearFlag = 0xff; @@ -181,7 +177,6 @@ std::optional<Edid> parseEdid(const DisplayIdentificationData& edid) { constexpr size_t kDescriptorCount = 4; constexpr size_t kDescriptorLength = 18; - static_assert(kDescriptorLength - kEdidHeaderLength < DeviceProductInfo::TEXT_BUFFER_SIZE); for (size_t i = 0; i < kDescriptorCount; i++) { if (view.size() < kDescriptorLength) { diff --git a/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp b/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp index c2ddfcee45..2c7a28164a 100644 --- a/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayIdentificationTest.cpp @@ -293,9 +293,9 @@ TEST(DisplayIdentificationTest, deviceProductInfo) { ASSERT_TRUE(displayIdInfo); ASSERT_TRUE(displayIdInfo->deviceProductInfo); const auto& info = *displayIdInfo->deviceProductInfo; - EXPECT_STREQ("", info.name.data()); + EXPECT_EQ("", info.name); EXPECT_STREQ("SEC", info.manufacturerPnpId.data()); - EXPECT_STREQ("12610", info.productId.data()); + EXPECT_EQ("12610", info.productId); ASSERT_TRUE(std::holds_alternative<ManufactureYear>(info.manufactureOrModelDate)); EXPECT_EQ(2011, std::get<ManufactureYear>(info.manufactureOrModelDate).year); } @@ -304,9 +304,9 @@ TEST(DisplayIdentificationTest, deviceProductInfo) { ASSERT_TRUE(displayIdInfo); ASSERT_TRUE(displayIdInfo->deviceProductInfo); const auto& info = *displayIdInfo->deviceProductInfo; - EXPECT_STREQ("HP ZR30w", info.name.data()); + EXPECT_EQ("HP ZR30w", info.name); EXPECT_STREQ("HWP", info.manufacturerPnpId.data()); - EXPECT_STREQ("10348", info.productId.data()); + EXPECT_EQ("10348", info.productId); ASSERT_TRUE(std::holds_alternative<ManufactureWeekAndYear>(info.manufactureOrModelDate)); const auto& date = std::get<ManufactureWeekAndYear>(info.manufactureOrModelDate); EXPECT_EQ(2012, date.year); @@ -317,9 +317,9 @@ TEST(DisplayIdentificationTest, deviceProductInfo) { ASSERT_TRUE(displayIdInfo); ASSERT_TRUE(displayIdInfo->deviceProductInfo); const auto& info = *displayIdInfo->deviceProductInfo; - EXPECT_STREQ("SAMSUNG", info.name.data()); + EXPECT_EQ("SAMSUNG", info.name); EXPECT_STREQ("SAM", info.manufacturerPnpId.data()); - EXPECT_STREQ("2302", info.productId.data()); + EXPECT_EQ("2302", info.productId); ASSERT_TRUE(std::holds_alternative<ManufactureWeekAndYear>(info.manufactureOrModelDate)); const auto& date = std::get<ManufactureWeekAndYear>(info.manufactureOrModelDate); EXPECT_EQ(2011, date.year); @@ -330,9 +330,9 @@ TEST(DisplayIdentificationTest, deviceProductInfo) { ASSERT_TRUE(displayIdInfo); ASSERT_TRUE(displayIdInfo->deviceProductInfo); const auto& info = *displayIdInfo->deviceProductInfo; - EXPECT_STREQ("Panasonic-TV", info.name.data()); + EXPECT_EQ("Panasonic-TV", info.name); EXPECT_STREQ("MEI", info.manufacturerPnpId.data()); - EXPECT_STREQ("41622", info.productId.data()); + EXPECT_EQ("41622", info.productId); ASSERT_TRUE(std::holds_alternative<ManufactureYear>(info.manufactureOrModelDate)); const auto& date = std::get<ManufactureYear>(info.manufactureOrModelDate); EXPECT_EQ(2019, date.year); @@ -342,9 +342,9 @@ TEST(DisplayIdentificationTest, deviceProductInfo) { ASSERT_TRUE(displayIdInfo); ASSERT_TRUE(displayIdInfo->deviceProductInfo); const auto& info = *displayIdInfo->deviceProductInfo; - EXPECT_STREQ("Hisense", info.name.data()); + EXPECT_EQ("Hisense", info.name); EXPECT_STREQ("HEC", info.manufacturerPnpId.data()); - EXPECT_STREQ("0", info.productId.data()); + EXPECT_EQ("0", info.productId); ASSERT_TRUE(std::holds_alternative<ManufactureWeekAndYear>(info.manufactureOrModelDate)); const auto& date = std::get<ManufactureWeekAndYear>(info.manufactureOrModelDate); EXPECT_EQ(2019, date.year); @@ -355,9 +355,9 @@ TEST(DisplayIdentificationTest, deviceProductInfo) { ASSERT_TRUE(displayIdInfo); ASSERT_TRUE(displayIdInfo->deviceProductInfo); const auto& info = *displayIdInfo->deviceProductInfo; - EXPECT_STREQ("LP2361", info.name.data()); + EXPECT_EQ("LP2361", info.name); EXPECT_STREQ("CTL", info.manufacturerPnpId.data()); - EXPECT_STREQ("9373", info.productId.data()); + EXPECT_EQ("9373", info.productId); ASSERT_TRUE(std::holds_alternative<ModelYear>(info.manufactureOrModelDate)); EXPECT_EQ(2013, std::get<ModelYear>(info.manufactureOrModelDate).year); } |