blob: c9b8d3993959f95603386461cd8a954ea42b068a [file] [log] [blame]
Adam Lesinski1ab598f2015-08-14 14:26:04 -07001/*
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
Adam Lesinskice5e56e2016-10-21 17:56:45 -070020#include <set>
21#include <unordered_set>
22
23#include "android-base/macros.h"
Mårten Kongstad24c9aa62018-06-20 08:46:41 +020024#include "androidfw/ConfigDescription.h"
Adam Lesinski1ef0fa92017-08-15 21:32:49 -070025#include "androidfw/StringPiece.h"
Adam Lesinskice5e56e2016-10-21 17:56:45 -070026
Adam Lesinski467f1712015-11-16 17:35:44 -080027#include "Resource.h"
Adam Lesinskic744ae82017-05-17 19:28:38 -070028#include "SdkConstants.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070029#include "process/IResourceTableConsumer.h"
Adam Lesinski467f1712015-11-16 17:35:44 -080030#include "xml/XmlDom.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070031
Adam Lesinski1ab598f2015-08-14 14:26:04 -070032namespace aapt {
33
34class ResourceTable;
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080035class ResourceEntry;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070036
Adam Lesinski1ef0fa92017-08-15 21:32:49 -070037// 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.
Adam Lesinski467f1712015-11-16 17:35:44 -080040struct CallSite {
Adam Lesinski1ef0fa92017-08-15 21:32:49 -070041 std::string package;
Adam Lesinski467f1712015-11-16 17:35:44 -080042};
43
Adam Lesinski1ef0fa92017-08-15 21:32:49 -070044// Determines whether a versioned resource should be created. If a versioned resource already
45// exists, it takes precedence.
Mårten Kongstad24c9aa62018-06-20 08:46:41 +020046bool ShouldGenerateVersionedResource(const ResourceEntry* entry,
47 const android::ConfigDescription& config,
Adam Lesinskic744ae82017-05-17 19:28:38 -070048 const ApiVersion sdk_version_to_generate);
49
Adam Lesinskibb94f322017-07-12 07:41:55 -070050// Finds the next largest ApiVersion of the config which is identical to the given config except
51// for sdkVersion.
Mårten Kongstad24c9aa62018-06-20 08:46:41 +020052ApiVersion FindNextApiVersionForConfig(const ResourceEntry* entry,
53 const android::ConfigDescription& config);
Adam Lesinski1ab598f2015-08-14 14:26:04 -070054
Adam Lesinskifb6312f2016-06-28 14:40:32 -070055class AutoVersioner : public IResourceTableConsumer {
Adam Lesinskicacb28f2016-10-19 12:18:14 -070056 public:
Adam Lesinskice5e56e2016-10-21 17:56:45 -070057 AutoVersioner() = default;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070058
Adam Lesinskice5e56e2016-10-21 17:56:45 -070059 bool Consume(IAaptContext* context, ResourceTable* table) override;
60
61 private:
62 DISALLOW_COPY_AND_ASSIGN(AutoVersioner);
Adam Lesinski1ab598f2015-08-14 14:26:04 -070063};
64
Adam Lesinski1ef0fa92017-08-15 21:32:49 -070065// 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.
Adam Lesinskice5e56e2016-10-21 17:56:45 -070085class 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
95class ResourceConfigValue;
96
97class ProductFilter : public IResourceTableConsumer {
98 public:
Adam Lesinskic744ae82017-05-17 19:28:38 -070099 using ResourceConfigValueIter = std::vector<std::unique_ptr<ResourceConfigValue>>::iterator;
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700100
Adam Lesinskic744ae82017-05-17 19:28:38 -0700101 explicit ProductFilter(std::unordered_set<std::string> products) : products_(products) {
102 }
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700103
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:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700111 DISALLOW_COPY_AND_ASSIGN(ProductFilter);
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700112
Adam Lesinskic744ae82017-05-17 19:28:38 -0700113 std::unordered_set<std::string> products_;
Adam Lesinski9f222042015-11-04 13:51:45 -0800114};
115
Adam Lesinski1ef0fa92017-08-15 21:32:49 -0700116// 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.
Alexandria Cornwalla7cc3f12016-08-16 13:33:32 -0700120class XmlNamespaceRemover : public IXmlResourceConsumer {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700121 public:
Adam Lesinskic744ae82017-05-17 19:28:38 -0700122 explicit XmlNamespaceRemover(bool keep_uris = false) : keep_uris_(keep_uris){};
Alexandria Cornwalla7cc3f12016-08-16 13:33:32 -0700123
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700124 bool Consume(IAaptContext* context, xml::XmlResource* resource) override;
125
126 private:
127 DISALLOW_COPY_AND_ASSIGN(XmlNamespaceRemover);
128
129 bool keep_uris_;
Alexandria Cornwalla7cc3f12016-08-16 13:33:32 -0700130};
131
Adam Lesinski1ef0fa92017-08-15 21:32:49 -0700132// 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.
Adam Lesinski9f222042015-11-04 13:51:45 -0800134class XmlReferenceLinker : public IXmlResourceConsumer {
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700135 public:
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700136 XmlReferenceLinker() = default;
137
138 bool Consume(IAaptContext* context, xml::XmlResource* resource) override;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700139
Adam Lesinskice5e56e2016-10-21 17:56:45 -0700140 private:
141 DISALLOW_COPY_AND_ASSIGN(XmlReferenceLinker);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700142};
143
Adam Lesinskicacb28f2016-10-19 12:18:14 -0700144} // namespace aapt
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700145
146#endif /* AAPT_LINKER_LINKERS_H */