diff options
Diffstat (limited to 'libs/input/DisplayTopologyGraph.cpp')
-rw-r--r-- | libs/input/DisplayTopologyGraph.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/libs/input/DisplayTopologyGraph.cpp b/libs/input/DisplayTopologyGraph.cpp new file mode 100644 index 0000000000..7ad9f163b8 --- /dev/null +++ b/libs/input/DisplayTopologyGraph.cpp @@ -0,0 +1,105 @@ +/* + * Copyright 2025 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 "DisplayTopologyValidator" + +#include <android-base/logging.h> +#include <ftl/enum.h> +#include <input/DisplayTopologyGraph.h> +#include <ui/LogicalDisplayId.h> + +#include <algorithm> + +namespace android { + +namespace { +DisplayTopologyPosition getOppositePosition(DisplayTopologyPosition position) { + switch (position) { + case DisplayTopologyPosition::LEFT: + return DisplayTopologyPosition::RIGHT; + case DisplayTopologyPosition::TOP: + return DisplayTopologyPosition::BOTTOM; + case DisplayTopologyPosition::RIGHT: + return DisplayTopologyPosition::LEFT; + case DisplayTopologyPosition::BOTTOM: + return DisplayTopologyPosition::TOP; + } +} + +bool validatePrimaryDisplay(const android::DisplayTopologyGraph& displayTopologyGraph) { + return displayTopologyGraph.primaryDisplayId != ui::LogicalDisplayId::INVALID && + displayTopologyGraph.graph.contains(displayTopologyGraph.primaryDisplayId); +} + +bool validateTopologyGraph(const android::DisplayTopologyGraph& displayTopologyGraph) { + for (const auto& [sourceDisplay, adjacentDisplays] : displayTopologyGraph.graph) { + for (const DisplayTopologyAdjacentDisplay& adjacentDisplay : adjacentDisplays) { + const auto adjacentGraphIt = displayTopologyGraph.graph.find(adjacentDisplay.displayId); + if (adjacentGraphIt == displayTopologyGraph.graph.end()) { + LOG(ERROR) << "Missing adjacent display in topology graph: " + << adjacentDisplay.displayId << " for source " << sourceDisplay; + return false; + } + const auto reverseEdgeIt = + std::find_if(adjacentGraphIt->second.begin(), adjacentGraphIt->second.end(), + [sourceDisplay](const DisplayTopologyAdjacentDisplay& + reverseAdjacentDisplay) { + return sourceDisplay == reverseAdjacentDisplay.displayId; + }); + if (reverseEdgeIt == adjacentGraphIt->second.end()) { + LOG(ERROR) << "Missing reverse edge in topology graph for: " << sourceDisplay + << " -> " << adjacentDisplay.displayId; + return false; + } + DisplayTopologyPosition expectedPosition = + getOppositePosition(adjacentDisplay.position); + if (reverseEdgeIt->position != expectedPosition) { + LOG(ERROR) << "Unexpected reverse edge for: " << sourceDisplay << " -> " + << adjacentDisplay.displayId + << " expected position: " << ftl::enum_string(expectedPosition) + << " actual " << ftl::enum_string(reverseEdgeIt->position); + return false; + } + if (reverseEdgeIt->offsetDp != -adjacentDisplay.offsetDp) { + LOG(ERROR) << "Unexpected reverse edge offset: " << sourceDisplay << " -> " + << adjacentDisplay.displayId + << " expected offset: " << -adjacentDisplay.offsetDp << " actual " + << reverseEdgeIt->offsetDp; + return false; + } + } + } + return true; +} + +bool validateDensities(const android::DisplayTopologyGraph& displayTopologyGraph) { + for (const auto& [sourceDisplay, adjacentDisplays] : displayTopologyGraph.graph) { + if (!displayTopologyGraph.displaysDensity.contains(sourceDisplay)) { + LOG(ERROR) << "Missing density value in topology graph for display: " << sourceDisplay; + return false; + } + } + return true; +} + +} // namespace + +bool DisplayTopologyGraph::isValid() const { + return validatePrimaryDisplay(*this) && validateTopologyGraph(*this) && + validateDensities(*this); +} + +} // namespace android |