1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef AAPT_LINKER_LINKERS_H 18 #define AAPT_LINKER_LINKERS_H 19 20 #include <set> 21 #include <unordered_set> 22 23 #include "android-base/macros.h" 24 25 #include "Resource.h" 26 #include "SdkConstants.h" 27 #include "process/IResourceTableConsumer.h" 28 #include "xml/XmlDom.h" 29 30 namespace aapt { 31 32 class ResourceTable; 33 class ResourceEntry; 34 struct ConfigDescription; 35 36 /** 37 * Defines the location in which a value exists. This determines visibility of 38 * other package's private symbols. 39 */ 40 struct CallSite { 41 ResourceNameRef resource; 42 }; 43 44 /** 45 * Determines whether a versioned resource should be created. If a versioned 46 * resource already exists, it takes precedence. 47 */ 48 bool ShouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config, 49 const ApiVersion sdk_version_to_generate); 50 51 // Finds the next largest ApiVersion of the config which is identical to the given config except 52 // for sdkVersion. 53 ApiVersion FindNextApiVersionForConfig(const ResourceEntry* entry, const ConfigDescription& config); 54 55 class AutoVersioner : public IResourceTableConsumer { 56 public: 57 AutoVersioner() = default; 58 59 bool Consume(IAaptContext* context, ResourceTable* table) override; 60 61 private: 62 DISALLOW_COPY_AND_ASSIGN(AutoVersioner); 63 }; 64 65 /** 66 * If any attribute resource values are defined as public, this consumer will 67 * move all private 68 * attribute resource values to a private ^private-attr type, avoiding backwards 69 * compatibility 70 * issues with new apps running on old platforms. 71 * 72 * The Android platform ignores resource attributes it doesn't recognize, so an 73 * app developer can 74 * use new attributes in their layout XML files without worrying about 75 * versioning. This assumption 76 * actually breaks on older platforms. OEMs may add private attributes that are 77 * used internally. 78 * AAPT originally assigned all private attributes IDs immediately proceeding 79 * the public attributes' 80 * IDs. 81 * 82 * This means that on a newer Android platform, an ID previously assigned to a 83 * private attribute 84 * may end up assigned to a public attribute. 85 * 86 * App developers assume using the newer attribute is safe on older platforms 87 * because it will 88 * be ignored. Instead, the platform thinks the new attribute is an older, 89 * private attribute and 90 * will interpret it as such. This leads to unintended styling and exceptions 91 * thrown due to 92 * unexpected types. 93 * 94 * By moving the private attributes to a completely different type, this ID 95 * conflict will never 96 * occur. 97 */ 98 class PrivateAttributeMover : public IResourceTableConsumer { 99 public: 100 PrivateAttributeMover() = default; 101 102 bool Consume(IAaptContext* context, ResourceTable* table) override; 103 104 private: 105 DISALLOW_COPY_AND_ASSIGN(PrivateAttributeMover); 106 }; 107 108 class ResourceConfigValue; 109 110 class ProductFilter : public IResourceTableConsumer { 111 public: 112 using ResourceConfigValueIter = std::vector<std::unique_ptr<ResourceConfigValue>>::iterator; 113 ProductFilter(std::unordered_set<std::string> products)114 explicit ProductFilter(std::unordered_set<std::string> products) : products_(products) { 115 } 116 117 ResourceConfigValueIter SelectProductToKeep( 118 const ResourceNameRef& name, const ResourceConfigValueIter begin, 119 const ResourceConfigValueIter end, IDiagnostics* diag); 120 121 bool Consume(IAaptContext* context, ResourceTable* table) override; 122 123 private: 124 DISALLOW_COPY_AND_ASSIGN(ProductFilter); 125 126 std::unordered_set<std::string> products_; 127 }; 128 129 /** 130 * Removes namespace nodes and URI information from the XmlResource. 131 * 132 * Once an XmlResource is processed by this consumer, it is no longer able to 133 * have its attributes 134 * parsed. As such, this XmlResource must have already been processed by 135 * XmlReferenceLinker. 136 */ 137 class XmlNamespaceRemover : public IXmlResourceConsumer { 138 public: keep_uris_(keep_uris)139 explicit XmlNamespaceRemover(bool keep_uris = false) : keep_uris_(keep_uris){}; 140 141 bool Consume(IAaptContext* context, xml::XmlResource* resource) override; 142 143 private: 144 DISALLOW_COPY_AND_ASSIGN(XmlNamespaceRemover); 145 146 bool keep_uris_; 147 }; 148 149 /** 150 * Resolves attributes in the XmlResource and compiles string values to resource 151 * values. 152 * Once an XmlResource is processed by this linker, it is ready to be flattened. 153 */ 154 class XmlReferenceLinker : public IXmlResourceConsumer { 155 public: 156 XmlReferenceLinker() = default; 157 158 bool Consume(IAaptContext* context, xml::XmlResource* resource) override; 159 160 private: 161 DISALLOW_COPY_AND_ASSIGN(XmlReferenceLinker); 162 }; 163 164 } // namespace aapt 165 166 #endif /* AAPT_LINKER_LINKERS_H */ 167