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 #include "androidfw/StringPiece.h" 25 26 #include "Resource.h" 27 #include "SdkConstants.h" 28 #include "process/IResourceTableConsumer.h" 29 #include "xml/XmlDom.h" 30 31 namespace aapt { 32 33 class ResourceTable; 34 class ResourceEntry; 35 struct ConfigDescription; 36 37 // Defines the context in which a resource value is defined. Most resources are defined with the 38 // implicit package name of their compilation context. Understanding the package name of a resource 39 // allows to determine visibility of other symbols which may or may not have their packages defined. 40 struct CallSite { 41 std::string package; 42 }; 43 44 // Determines whether a versioned resource should be created. If a versioned resource already 45 // exists, it takes precedence. 46 bool ShouldGenerateVersionedResource(const ResourceEntry* entry, const ConfigDescription& config, 47 const ApiVersion sdk_version_to_generate); 48 49 // Finds the next largest ApiVersion of the config which is identical to the given config except 50 // for sdkVersion. 51 ApiVersion FindNextApiVersionForConfig(const ResourceEntry* entry, const ConfigDescription& config); 52 53 class AutoVersioner : public IResourceTableConsumer { 54 public: 55 AutoVersioner() = default; 56 57 bool Consume(IAaptContext* context, ResourceTable* table) override; 58 59 private: 60 DISALLOW_COPY_AND_ASSIGN(AutoVersioner); 61 }; 62 63 // If any attribute resource values are defined as public, this consumer will move all private 64 // attribute resource values to a private ^private-attr type, avoiding backwards compatibility 65 // issues with new apps running on old platforms. 66 // 67 // The Android platform ignores resource attributes it doesn't recognize, so an app developer can 68 // use new attributes in their layout XML files without worrying about versioning. This assumption 69 // actually breaks on older platforms. OEMs may add private attributes that are used internally. 70 // AAPT originally assigned all private attributes IDs immediately proceeding the public attributes' 71 // IDs. 72 // 73 // This means that on a newer Android platform, an ID previously assigned to a private attribute 74 // may end up assigned to a public attribute. 75 // 76 // App developers assume using the newer attribute is safe on older platforms because it will 77 // be ignored. Instead, the platform thinks the new attribute is an older, private attribute and 78 // will interpret it as such. This leads to unintended styling and exceptions thrown due to 79 // unexpected types. 80 // 81 // By moving the private attributes to a completely different type, this ID conflict will never 82 // occur. 83 class PrivateAttributeMover : public IResourceTableConsumer { 84 public: 85 PrivateAttributeMover() = default; 86 87 bool Consume(IAaptContext* context, ResourceTable* table) override; 88 89 private: 90 DISALLOW_COPY_AND_ASSIGN(PrivateAttributeMover); 91 }; 92 93 class ResourceConfigValue; 94 95 class ProductFilter : public IResourceTableConsumer { 96 public: 97 using ResourceConfigValueIter = std::vector<std::unique_ptr<ResourceConfigValue>>::iterator; 98 99 explicit ProductFilter(std::unordered_set<std::string> products) : products_(products) { 100 } 101 102 ResourceConfigValueIter SelectProductToKeep( 103 const ResourceNameRef& name, const ResourceConfigValueIter begin, 104 const ResourceConfigValueIter end, IDiagnostics* diag); 105 106 bool Consume(IAaptContext* context, ResourceTable* table) override; 107 108 private: 109 DISALLOW_COPY_AND_ASSIGN(ProductFilter); 110 111 std::unordered_set<std::string> products_; 112 }; 113 114 // Removes namespace nodes and URI information from the XmlResource. 115 // 116 // Once an XmlResource is processed by this consumer, it is no longer able to have its attributes 117 // parsed. As such, this XmlResource must have already been processed by XmlReferenceLinker. 118 class XmlNamespaceRemover : public IXmlResourceConsumer { 119 public: 120 explicit XmlNamespaceRemover(bool keep_uris = false) : keep_uris_(keep_uris){}; 121 122 bool Consume(IAaptContext* context, xml::XmlResource* resource) override; 123 124 private: 125 DISALLOW_COPY_AND_ASSIGN(XmlNamespaceRemover); 126 127 bool keep_uris_; 128 }; 129 130 // Resolves attributes in the XmlResource and compiles string values to resource values. 131 // Once an XmlResource is processed by this linker, it is ready to be flattened. 132 class XmlReferenceLinker : public IXmlResourceConsumer { 133 public: 134 XmlReferenceLinker() = default; 135 136 bool Consume(IAaptContext* context, xml::XmlResource* resource) override; 137 138 private: 139 DISALLOW_COPY_AND_ASSIGN(XmlReferenceLinker); 140 }; 141 142 } // namespace aapt 143 144 #endif /* AAPT_LINKER_LINKERS_H */ 145