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