1*d57664e9SAndroid Build Coastguard Worker /* 2*d57664e9SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*d57664e9SAndroid Build Coastguard Worker * 4*d57664e9SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*d57664e9SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*d57664e9SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*d57664e9SAndroid Build Coastguard Worker * 8*d57664e9SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*d57664e9SAndroid Build Coastguard Worker * 10*d57664e9SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*d57664e9SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*d57664e9SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*d57664e9SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*d57664e9SAndroid Build Coastguard Worker * limitations under the License. 15*d57664e9SAndroid Build Coastguard Worker */ 16*d57664e9SAndroid Build Coastguard Worker 17*d57664e9SAndroid Build Coastguard Worker #ifndef AAPT_DOMINATOR_TREE_H 18*d57664e9SAndroid Build Coastguard Worker #define AAPT_DOMINATOR_TREE_H 19*d57664e9SAndroid Build Coastguard Worker 20*d57664e9SAndroid Build Coastguard Worker #include <map> 21*d57664e9SAndroid Build Coastguard Worker #include <memory> 22*d57664e9SAndroid Build Coastguard Worker #include <string> 23*d57664e9SAndroid Build Coastguard Worker #include <vector> 24*d57664e9SAndroid Build Coastguard Worker 25*d57664e9SAndroid Build Coastguard Worker #include "ResourceTable.h" 26*d57664e9SAndroid Build Coastguard Worker 27*d57664e9SAndroid Build Coastguard Worker namespace aapt { 28*d57664e9SAndroid Build Coastguard Worker 29*d57664e9SAndroid Build Coastguard Worker /** 30*d57664e9SAndroid Build Coastguard Worker * A dominator tree of configurations as defined by resolution rules for Android 31*d57664e9SAndroid Build Coastguard Worker * resources. 32*d57664e9SAndroid Build Coastguard Worker * 33*d57664e9SAndroid Build Coastguard Worker * A node in the tree represents a resource configuration. 34*d57664e9SAndroid Build Coastguard Worker * 35*d57664e9SAndroid Build Coastguard Worker * The tree has the following property: 36*d57664e9SAndroid Build Coastguard Worker * 37*d57664e9SAndroid Build Coastguard Worker * Each child of a given configuration defines a strict superset of qualifiers 38*d57664e9SAndroid Build Coastguard Worker * and has a value that is at least as specific as that of its ancestors. A 39*d57664e9SAndroid Build Coastguard Worker * value is "at least as specific" if it is either identical or it represents a 40*d57664e9SAndroid Build Coastguard Worker * stronger requirement. 41*d57664e9SAndroid Build Coastguard Worker * For example, v21 is more specific than v11, and w1200dp is more specific than 42*d57664e9SAndroid Build Coastguard Worker * w800dp. 43*d57664e9SAndroid Build Coastguard Worker * 44*d57664e9SAndroid Build Coastguard Worker * The dominator tree relies on the underlying configurations passed to it. If 45*d57664e9SAndroid Build Coastguard Worker * the configurations passed to the dominator tree go out of scope, the tree 46*d57664e9SAndroid Build Coastguard Worker * will exhibit undefined behavior. 47*d57664e9SAndroid Build Coastguard Worker */ 48*d57664e9SAndroid Build Coastguard Worker class DominatorTree { 49*d57664e9SAndroid Build Coastguard Worker public: 50*d57664e9SAndroid Build Coastguard Worker explicit DominatorTree( 51*d57664e9SAndroid Build Coastguard Worker const std::vector<std::unique_ptr<ResourceConfigValue>>& configs); 52*d57664e9SAndroid Build Coastguard Worker 53*d57664e9SAndroid Build Coastguard Worker class Node { 54*d57664e9SAndroid Build Coastguard Worker public: 55*d57664e9SAndroid Build Coastguard Worker explicit Node(ResourceConfigValue* value = nullptr, Node* parent = nullptr) value_(value)56*d57664e9SAndroid Build Coastguard Worker : value_(value), parent_(parent) {} 57*d57664e9SAndroid Build Coastguard Worker value()58*d57664e9SAndroid Build Coastguard Worker inline ResourceConfigValue* value() const { return value_; } 59*d57664e9SAndroid Build Coastguard Worker parent()60*d57664e9SAndroid Build Coastguard Worker inline Node* parent() const { return parent_; } 61*d57664e9SAndroid Build Coastguard Worker is_root_node()62*d57664e9SAndroid Build Coastguard Worker inline bool is_root_node() const { return !value_; } 63*d57664e9SAndroid Build Coastguard Worker children()64*d57664e9SAndroid Build Coastguard Worker inline const std::vector<std::unique_ptr<Node>>& children() const { 65*d57664e9SAndroid Build Coastguard Worker return children_; 66*d57664e9SAndroid Build Coastguard Worker } 67*d57664e9SAndroid Build Coastguard Worker 68*d57664e9SAndroid Build Coastguard Worker bool TryAddChild(std::unique_ptr<Node> new_child); 69*d57664e9SAndroid Build Coastguard Worker 70*d57664e9SAndroid Build Coastguard Worker private: 71*d57664e9SAndroid Build Coastguard Worker bool AddChild(std::unique_ptr<Node> new_child); 72*d57664e9SAndroid Build Coastguard Worker bool Dominates(const Node* other) const; 73*d57664e9SAndroid Build Coastguard Worker 74*d57664e9SAndroid Build Coastguard Worker ResourceConfigValue* value_; 75*d57664e9SAndroid Build Coastguard Worker Node* parent_; 76*d57664e9SAndroid Build Coastguard Worker std::vector<std::unique_ptr<Node>> children_; 77*d57664e9SAndroid Build Coastguard Worker 78*d57664e9SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Node); 79*d57664e9SAndroid Build Coastguard Worker }; 80*d57664e9SAndroid Build Coastguard Worker 81*d57664e9SAndroid Build Coastguard Worker struct Visitor { 82*d57664e9SAndroid Build Coastguard Worker virtual ~Visitor() = default; 83*d57664e9SAndroid Build Coastguard Worker virtual void VisitTree(const std::string& product, Node* root) = 0; 84*d57664e9SAndroid Build Coastguard Worker }; 85*d57664e9SAndroid Build Coastguard Worker 86*d57664e9SAndroid Build Coastguard Worker class BottomUpVisitor : public Visitor { 87*d57664e9SAndroid Build Coastguard Worker public: 88*d57664e9SAndroid Build Coastguard Worker virtual ~BottomUpVisitor() = default; 89*d57664e9SAndroid Build Coastguard Worker VisitTree(const std::string & product,Node * root)90*d57664e9SAndroid Build Coastguard Worker void VisitTree(const std::string& product, Node* root) override { 91*d57664e9SAndroid Build Coastguard Worker for (auto& child : root->children()) { 92*d57664e9SAndroid Build Coastguard Worker VisitNode(child.get()); 93*d57664e9SAndroid Build Coastguard Worker } 94*d57664e9SAndroid Build Coastguard Worker } 95*d57664e9SAndroid Build Coastguard Worker 96*d57664e9SAndroid Build Coastguard Worker virtual void VisitConfig(Node* node) = 0; 97*d57664e9SAndroid Build Coastguard Worker 98*d57664e9SAndroid Build Coastguard Worker private: VisitNode(Node * node)99*d57664e9SAndroid Build Coastguard Worker void VisitNode(Node* node) { 100*d57664e9SAndroid Build Coastguard Worker for (auto& child : node->children()) { 101*d57664e9SAndroid Build Coastguard Worker VisitNode(child.get()); 102*d57664e9SAndroid Build Coastguard Worker } 103*d57664e9SAndroid Build Coastguard Worker VisitConfig(node); 104*d57664e9SAndroid Build Coastguard Worker } 105*d57664e9SAndroid Build Coastguard Worker }; 106*d57664e9SAndroid Build Coastguard Worker 107*d57664e9SAndroid Build Coastguard Worker void Accept(Visitor* visitor); 108*d57664e9SAndroid Build Coastguard Worker product_roots()109*d57664e9SAndroid Build Coastguard Worker inline const std::map<std::string, Node>& product_roots() const { 110*d57664e9SAndroid Build Coastguard Worker return product_roots_; 111*d57664e9SAndroid Build Coastguard Worker } 112*d57664e9SAndroid Build Coastguard Worker 113*d57664e9SAndroid Build Coastguard Worker private: 114*d57664e9SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(DominatorTree); 115*d57664e9SAndroid Build Coastguard Worker 116*d57664e9SAndroid Build Coastguard Worker std::map<std::string, Node> product_roots_; 117*d57664e9SAndroid Build Coastguard Worker }; 118*d57664e9SAndroid Build Coastguard Worker 119*d57664e9SAndroid Build Coastguard Worker } // namespace aapt 120*d57664e9SAndroid Build Coastguard Worker 121*d57664e9SAndroid Build Coastguard Worker #endif // AAPT_DOMINATOR_TREE_H 122