blob: 8ffff1f707107fdfe204e0babf474147d70fd679 [file] [log] [blame]
Adam Lesinski6f6ceb72014-11-14 14:48:12 -08001/*
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_RESOURCE_TABLE_H
18#define AAPT_RESOURCE_TABLE_H
19
20#include "ConfigDescription.h"
Adam Lesinski1ab598f2015-08-14 14:26:04 -070021#include "Diagnostics.h"
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080022#include "Resource.h"
23#include "ResourceValues.h"
24#include "Source.h"
25#include "StringPool.h"
26
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080027#include <android-base/macros.h>
28#include <map>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080029#include <memory>
30#include <string>
31#include <tuple>
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080032#include <unordered_map>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080033#include <vector>
34
35namespace aapt {
36
Adam Lesinski9e10ac72015-10-16 14:37:48 -070037enum class SymbolState {
38 kUndefined,
39 kPublic,
40 kPrivate
41};
42
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080043/**
44 * The Public status of a resource.
45 */
Adam Lesinski9e10ac72015-10-16 14:37:48 -070046struct Symbol {
47 SymbolState state = SymbolState::kUndefined;
Adam Lesinski1ab598f2015-08-14 14:26:04 -070048 Source source;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080049 std::u16string comment;
50};
51
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080052class ResourceConfigValue {
53public:
54 /**
55 * The configuration for which this value is defined.
56 */
57 const ConfigDescription config;
58
59 /**
60 * The product for which this value is defined.
61 */
62 const std::string product;
63
64 /**
65 * The actual Value.
66 */
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080067 std::unique_ptr<Value> value;
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080068
69 ResourceConfigValue(const ConfigDescription& config, const StringPiece& product) :
70 config(config), product(product.toString()) { }
71
72private:
73 DISALLOW_COPY_AND_ASSIGN(ResourceConfigValue);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080074};
75
76/**
77 * Represents a resource entry, which may have
78 * varying values for each defined configuration.
79 */
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080080class ResourceEntry {
81public:
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080082 /**
83 * The name of the resource. Immutable, as
84 * this determines the order of this resource
85 * when doing lookups.
86 */
87 const std::u16string name;
88
89 /**
90 * The entry ID for this resource.
91 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -070092 Maybe<uint16_t> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080093
94 /**
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -080095 * Whether this resource is public (and must maintain the same entry ID across builds).
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080096 */
Adam Lesinski9e10ac72015-10-16 14:37:48 -070097 Symbol symbolStatus;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080098
99 /**
100 * The resource's values for each configuration.
101 */
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800102 std::vector<std::unique_ptr<ResourceConfigValue>> values;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800103
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700104 ResourceEntry(const StringPiece16& name) : name(name.toString()) { }
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800105
106 ResourceConfigValue* findValue(const ConfigDescription& config);
107 ResourceConfigValue* findValue(const ConfigDescription& config, const StringPiece& product);
108 ResourceConfigValue* findOrCreateValue(const ConfigDescription& config,
109 const StringPiece& product);
110 std::vector<ResourceConfigValue*> findAllValues(const ConfigDescription& config);
111
112private:
113 DISALLOW_COPY_AND_ASSIGN(ResourceEntry);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800114};
115
116/**
117 * Represents a resource type, which holds entries defined
118 * for this type.
119 */
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800120class ResourceTableType {
121public:
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800122 /**
123 * The logical type of resource (string, drawable, layout, etc.).
124 */
125 const ResourceType type;
126
127 /**
128 * The type ID for this resource.
129 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700130 Maybe<uint8_t> id;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800131
132 /**
133 * Whether this type is public (and must maintain the same
134 * type ID across builds).
135 */
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700136 Symbol symbolStatus;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800137
138 /**
139 * List of resources for this type.
140 */
141 std::vector<std::unique_ptr<ResourceEntry>> entries;
142
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700143 explicit ResourceTableType(const ResourceType type) : type(type) { }
144
145 ResourceEntry* findEntry(const StringPiece16& name);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700146 ResourceEntry* findOrCreateEntry(const StringPiece16& name);
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800147
148private:
149 DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700150};
151
152enum class PackageType {
153 System,
154 Vendor,
155 App,
156 Dynamic
157};
158
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800159class ResourceTablePackage {
160public:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700161 PackageType type = PackageType::App;
162 Maybe<uint8_t> id;
163 std::u16string name;
164
165 std::vector<std::unique_ptr<ResourceTableType>> types;
166
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800167 ResourceTablePackage() = default;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700168 ResourceTableType* findType(ResourceType type);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700169 ResourceTableType* findOrCreateType(const ResourceType type);
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800170
171private:
172 DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800173};
174
175/**
176 * The container and index for all resources defined for an app. This gets
177 * flattened into a binary resource table (resources.arsc).
178 */
179class ResourceTable {
180public:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700181 ResourceTable() = default;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800182
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700183 /**
184 * When a collision of resources occurs, this method decides which value to keep.
185 * Returns -1 if the existing value should be chosen.
186 * Returns 0 if the collision can not be resolved (error).
187 * Returns 1 if the incoming value should be chosen.
188 */
189 static int resolveValueCollision(Value* existing, Value* incoming);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800190
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800191 bool addResource(const ResourceNameRef& name,
192 const ConfigDescription& config,
193 const StringPiece& product,
194 std::unique_ptr<Value> value,
Adam Lesinskie78fd612015-10-22 12:48:43 -0700195 IDiagnostics* diag);
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700196
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800197 bool addResource(const ResourceNameRef& name,
198 const ResourceId resId,
199 const ConfigDescription& config,
200 const StringPiece& product,
201 std::unique_ptr<Value> value,
202 IDiagnostics* diag);
203
204 bool addFileReference(const ResourceNameRef& name,
205 const ConfigDescription& config,
206 const Source& source,
207 const StringPiece16& path,
Adam Lesinskifb48d292015-11-07 15:52:13 -0800208 IDiagnostics* diag);
209
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800210 bool addFileReference(const ResourceNameRef& name,
211 const ConfigDescription& config,
212 const Source& source,
213 const StringPiece16& path,
214 std::function<int(Value*,Value*)> conflictResolver,
215 IDiagnostics* diag);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800216
Adam Lesinski330edcd2015-05-04 17:40:56 -0700217 /**
218 * Same as addResource, but doesn't verify the validity of the name. This is used
219 * when loading resources from an existing binary resource table that may have mangled
220 * names.
221 */
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800222 bool addResourceAllowMangled(const ResourceNameRef& name,
223 const ConfigDescription& config,
224 const StringPiece& product,
225 std::unique_ptr<Value> value,
Adam Lesinski9e10ac72015-10-16 14:37:48 -0700226 IDiagnostics* diag);
227
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800228 bool addResourceAllowMangled(const ResourceNameRef& name,
229 const ResourceId id,
230 const ConfigDescription& config,
231 const StringPiece& product,
232 std::unique_ptr<Value> value,
233 IDiagnostics* diag);
Adam Lesinskie78fd612015-10-22 12:48:43 -0700234
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800235 bool setSymbolState(const ResourceNameRef& name,
236 const ResourceId resId,
237 const Symbol& symbol,
238 IDiagnostics* diag);
239
240 bool setSymbolStateAllowMangled(const ResourceNameRef& name,
241 const ResourceId resId,
242 const Symbol& symbol,
243 IDiagnostics* diag);
Adam Lesinskie78fd612015-10-22 12:48:43 -0700244
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700245 struct SearchResult {
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700246 ResourceTablePackage* package;
247 ResourceTableType* type;
248 ResourceEntry* entry;
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700249 };
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800250
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700251 Maybe<SearchResult> findResource(const ResourceNameRef& name);
Adam Lesinski769de982015-04-10 19:43:55 -0700252
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800253 /**
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700254 * The string pool used by this resource table. Values that reference strings must use
255 * this pool to create their strings.
256 *
257 * NOTE: `stringPool` must come before `packages` so that it is destroyed after.
258 * When `string pool` references are destroyed (as they will be when `packages`
259 * is destroyed), they decrement a refCount, which would cause invalid
260 * memory access if the pool was already destroyed.
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800261 */
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700262 StringPool stringPool;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800263
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700264 /**
265 * The list of packages in this table, sorted alphabetically by package name.
266 */
267 std::vector<std::unique_ptr<ResourceTablePackage>> packages;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800268
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700269 /**
270 * Returns the package struct with the given name, or nullptr if such a package does not
271 * exist. The empty string is a valid package and typically is used to represent the
272 * 'current' package before it is known to the ResourceTable.
273 */
274 ResourceTablePackage* findPackage(const StringPiece16& name);
275
276 ResourceTablePackage* findPackageById(uint8_t id);
277
Adam Lesinski9ba47d82015-10-13 11:37:10 -0700278 ResourceTablePackage* createPackage(const StringPiece16& name, Maybe<uint8_t> id = {});
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800279
280private:
Adam Lesinski1ab598f2015-08-14 14:26:04 -0700281 ResourceTablePackage* findOrCreatePackage(const StringPiece16& name);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800282
Adam Lesinskifb48d292015-11-07 15:52:13 -0800283 bool addResourceImpl(const ResourceNameRef& name,
284 ResourceId resId,
285 const ConfigDescription& config,
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800286 const StringPiece& product,
Adam Lesinskifb48d292015-11-07 15:52:13 -0800287 std::unique_ptr<Value> value,
288 const char16_t* validChars,
289 std::function<int(Value*,Value*)> conflictResolver,
290 IDiagnostics* diag);
291
Adam Lesinskie4bb9eb2016-02-12 22:18:51 -0800292 bool setSymbolStateImpl(const ResourceNameRef& name,
293 ResourceId resId,
294 const Symbol& symbol,
295 const char16_t* validChars,
296 IDiagnostics* diag);
297
298 DISALLOW_COPY_AND_ASSIGN(ResourceTable);
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800299};
300
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800301} // namespace aapt
302
303#endif // AAPT_RESOURCE_TABLE_H