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 "Resource.h" 24 #include "SdkConstants.h" 25 #include "android-base/macros.h" 26 #include "android-base/result.h" 27 #include "androidfw/ConfigDescription.h" 28 #include "androidfw/StringPiece.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 // Removes namespace nodes and URI information from the XmlResource. 96 // 97 // Once an XmlResource is processed by this consumer, it is no longer able to have its attributes 98 // parsed. As such, this XmlResource must have already been processed by XmlReferenceLinker. 99 class XmlNamespaceRemover : public IXmlResourceConsumer { 100 public: keep_uris_(keep_uris)101 explicit XmlNamespaceRemover(bool keep_uris = false) : keep_uris_(keep_uris){}; 102 103 bool Consume(IAaptContext* context, xml::XmlResource* resource) override; 104 105 private: 106 DISALLOW_COPY_AND_ASSIGN(XmlNamespaceRemover); 107 108 bool keep_uris_; 109 }; 110 111 // Resolves attributes in the XmlResource and compiles string values to resource values. 112 // Once an XmlResource is processed by this linker, it is ready to be flattened. 113 class XmlReferenceLinker : public IXmlResourceConsumer { 114 public: XmlReferenceLinker(ResourceTable * table)115 explicit XmlReferenceLinker(ResourceTable* table) : table_(table) { 116 } 117 118 bool Consume(IAaptContext* context, xml::XmlResource* resource) override; 119 120 private: 121 DISALLOW_COPY_AND_ASSIGN(XmlReferenceLinker); 122 ResourceTable* table_; 123 }; 124 125 } // namespace aapt 126 127 #endif /* AAPT_LINKER_LINKERS_H */ 128