blob: 30336e27b907795f27edf9223bbf63c301f15fe7 [file] [log] [blame]
Adam Lesinskiefeb7af2017-08-02 14:57:43 -07001/*
2 * Copyright (C) 2017 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#include "test/Builders.h"
18
Jeremy Meyer56f36e82022-05-20 20:35:42 +000019#include "Diagnostics.h"
Adam Lesinskiefeb7af2017-08-02 14:57:43 -070020#include "android-base/logging.h"
21#include "androidfw/StringPiece.h"
Adam Lesinski00451162017-10-03 07:44:08 -070022#include "io/StringStream.h"
Adam Lesinskiefeb7af2017-08-02 14:57:43 -070023#include "test/Common.h"
24#include "util/Util.h"
25
Shane Farmerefe45392017-08-21 14:39:28 -070026using ::aapt::configuration::Abi;
27using ::aapt::configuration::AndroidSdk;
Shane Farmercb6c3f92017-11-27 13:19:36 -080028using ::aapt::configuration::ConfiguredArtifact;
Shane Farmer78c43d72017-12-04 09:08:38 -080029using ::aapt::configuration::GetOrCreateGroup;
Adam Lesinskiefeb7af2017-08-02 14:57:43 -070030using ::aapt::io::StringInputStream;
MÃ¥rten Kongstad24c9aa62018-06-20 08:46:41 +020031using ::android::ConfigDescription;
Adam Lesinskiefeb7af2017-08-02 14:57:43 -070032using ::android::StringPiece;
33
34namespace aapt {
35namespace test {
36
Adam Lesinskiefeb7af2017-08-02 14:57:43 -070037ResourceTableBuilder& ResourceTableBuilder::AddSimple(const StringPiece& name,
38 const ResourceId& id) {
39 return AddValue(name, id, util::make_unique<Id>());
40}
41
42ResourceTableBuilder& ResourceTableBuilder::AddSimple(const StringPiece& name,
43 const ConfigDescription& config,
44 const ResourceId& id) {
45 return AddValue(name, config, id, util::make_unique<Id>());
46}
47
48ResourceTableBuilder& ResourceTableBuilder::AddReference(const StringPiece& name,
49 const StringPiece& ref) {
50 return AddReference(name, {}, ref);
51}
52
53ResourceTableBuilder& ResourceTableBuilder::AddReference(const StringPiece& name,
54 const ResourceId& id,
55 const StringPiece& ref) {
56 return AddValue(name, id, util::make_unique<Reference>(ParseNameOrDie(ref)));
57}
58
59ResourceTableBuilder& ResourceTableBuilder::AddString(const StringPiece& name,
60 const StringPiece& str) {
61 return AddString(name, {}, str);
62}
63
64ResourceTableBuilder& ResourceTableBuilder::AddString(const StringPiece& name, const ResourceId& id,
65 const StringPiece& str) {
66 return AddValue(name, id, util::make_unique<String>(table_->string_pool.MakeRef(str)));
67}
68
69ResourceTableBuilder& ResourceTableBuilder::AddString(const StringPiece& name, const ResourceId& id,
70 const ConfigDescription& config,
71 const StringPiece& str) {
72 return AddValue(name, config, id, util::make_unique<String>(table_->string_pool.MakeRef(str)));
73}
74
75ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name,
Adam Lesinski8780eb62017-10-31 17:44:39 -070076 const StringPiece& path,
77 io::IFile* file) {
78 return AddFileReference(name, {}, path, file);
Adam Lesinskiefeb7af2017-08-02 14:57:43 -070079}
80
81ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name,
82 const ResourceId& id,
Adam Lesinski8780eb62017-10-31 17:44:39 -070083 const StringPiece& path,
84 io::IFile* file) {
85 auto file_ref = util::make_unique<FileReference>(table_->string_pool.MakeRef(path));
86 file_ref->file = file;
87 return AddValue(name, id, std::move(file_ref));
Adam Lesinskiefeb7af2017-08-02 14:57:43 -070088}
89
90ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name,
91 const StringPiece& path,
Adam Lesinski8780eb62017-10-31 17:44:39 -070092 const ConfigDescription& config,
93 io::IFile* file) {
94 auto file_ref = util::make_unique<FileReference>(table_->string_pool.MakeRef(path));
95 file_ref->file = file;
96 return AddValue(name, config, {}, std::move(file_ref));
Adam Lesinskiefeb7af2017-08-02 14:57:43 -070097}
98
99ResourceTableBuilder& ResourceTableBuilder::AddValue(const StringPiece& name,
100 std::unique_ptr<Value> value) {
101 return AddValue(name, {}, std::move(value));
102}
103
104ResourceTableBuilder& ResourceTableBuilder::AddValue(const StringPiece& name, const ResourceId& id,
105 std::unique_ptr<Value> value) {
106 return AddValue(name, {}, id, std::move(value));
107}
108
109ResourceTableBuilder& ResourceTableBuilder::AddValue(const StringPiece& name,
110 const ConfigDescription& config,
111 const ResourceId& id,
112 std::unique_ptr<Value> value) {
113 ResourceName res_name = ParseNameOrDie(name);
Ryan Mitchell1d008d12021-03-19 14:54:17 -0700114 NewResourceBuilder builder(res_name);
115 builder.SetValue(std::move(value), config).SetAllowMangled(true);
116 if (id.id != 0U) {
117 builder.SetId(id);
118 }
119
120 CHECK(table_->AddResource(builder.Build(), GetDiagnostics()));
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700121 return *this;
122}
123
124ResourceTableBuilder& ResourceTableBuilder::SetSymbolState(const StringPiece& name,
Adam Lesinski71be7052017-12-12 16:48:07 -0800125 const ResourceId& id,
126 Visibility::Level level,
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700127 bool allow_new) {
128 ResourceName res_name = ParseNameOrDie(name);
Ryan Mitchell1d008d12021-03-19 14:54:17 -0700129 NewResourceBuilder builder(res_name);
130 builder.SetVisibility({level}).SetAllowNew({}).SetAllowMangled(true);
131 if (id.id != 0U) {
132 builder.SetId(id);
133 }
134
135 CHECK(table_->AddResource(builder.Build(), GetDiagnostics()));
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700136 return *this;
137}
138
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800139ResourceTableBuilder& ResourceTableBuilder::SetOverlayable(const StringPiece& name,
Ryan Mitchell54237ff2018-12-13 15:44:29 -0800140 const OverlayableItem& overlayable) {
Ryan Mitchell1bb1fe02018-11-16 11:21:41 -0800141
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700142 ResourceName res_name = ParseNameOrDie(name);
Ryan Mitchell1d008d12021-03-19 14:54:17 -0700143 CHECK(table_->AddResource(
144 NewResourceBuilder(res_name).SetOverlayable(overlayable).SetAllowMangled(true).Build(),
145 GetDiagnostics()));
146 return *this;
147}
148
149ResourceTableBuilder& ResourceTableBuilder::Add(NewResource&& res) {
150 CHECK(table_->AddResource(std::move(res), GetDiagnostics()));
Ryan Mitchelle4e989c2018-10-29 02:21:50 -0700151 return *this;
152}
153
Jeremy Meyer56f36e82022-05-20 20:35:42 +0000154android::StringPool* ResourceTableBuilder::string_pool() {
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700155 return &table_->string_pool;
156}
157
158std::unique_ptr<ResourceTable> ResourceTableBuilder::Build() {
159 return std::move(table_);
160}
161
Ryan Mitchell4382e442021-07-14 12:53:01 -0700162std::unique_ptr<Reference> BuildReference(const StringPiece& ref,
163 const std::optional<ResourceId>& id) {
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700164 std::unique_ptr<Reference> reference = util::make_unique<Reference>(ParseNameOrDie(ref));
165 reference->id = id;
166 return reference;
167}
168
169std::unique_ptr<BinaryPrimitive> BuildPrimitive(uint8_t type, uint32_t data) {
170 android::Res_value value = {};
171 value.size = sizeof(value);
172 value.dataType = type;
173 value.data = data;
174 return util::make_unique<BinaryPrimitive>(value);
175}
176
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800177AttributeBuilder::AttributeBuilder()
178 : attr_(util::make_unique<Attribute>(android::ResTable_map::TYPE_ANY)) {
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700179}
180
181AttributeBuilder& AttributeBuilder::SetTypeMask(uint32_t typeMask) {
182 attr_->type_mask = typeMask;
183 return *this;
184}
185
Adam Lesinski73bff1e2017-12-08 16:06:10 -0800186AttributeBuilder& AttributeBuilder::SetWeak(bool weak) {
187 attr_->SetWeak(weak);
188 return *this;
189}
190
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700191AttributeBuilder& AttributeBuilder::AddItem(const StringPiece& name, uint32_t value) {
192 attr_->symbols.push_back(
193 Attribute::Symbol{Reference(ResourceName({}, ResourceType::kId, name)), value});
194 return *this;
195}
196
197std::unique_ptr<Attribute> AttributeBuilder::Build() {
198 return std::move(attr_);
199}
200
201StyleBuilder& StyleBuilder::SetParent(const StringPiece& str) {
202 style_->parent = Reference(ParseNameOrDie(str));
203 return *this;
204}
205
206StyleBuilder& StyleBuilder::AddItem(const StringPiece& str, std::unique_ptr<Item> value) {
207 style_->entries.push_back(Style::Entry{Reference(ParseNameOrDie(str)), std::move(value)});
208 return *this;
209}
210
211StyleBuilder& StyleBuilder::AddItem(const StringPiece& str, const ResourceId& id,
212 std::unique_ptr<Item> value) {
213 AddItem(str, std::move(value));
214 style_->entries.back().key.id = id;
215 return *this;
216}
217
218std::unique_ptr<Style> StyleBuilder::Build() {
219 return std::move(style_);
220}
221
Ryan Mitchell4382e442021-07-14 12:53:01 -0700222StyleableBuilder& StyleableBuilder::AddItem(const StringPiece& str,
223 const std::optional<ResourceId>& id) {
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700224 styleable_->entries.push_back(Reference(ParseNameOrDie(str)));
225 styleable_->entries.back().id = id;
226 return *this;
227}
228
229std::unique_ptr<Styleable> StyleableBuilder::Build() {
230 return std::move(styleable_);
231}
232
233std::unique_ptr<xml::XmlResource> BuildXmlDom(const StringPiece& str) {
234 std::string input = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
235 input.append(str.data(), str.size());
236 StringInputStream in(input);
237 StdErrDiagnostics diag;
Jeremy Meyer56f36e82022-05-20 20:35:42 +0000238 std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, &diag, android::Source("test.xml"));
Adam Lesinski6b372992017-08-09 10:54:23 -0700239 CHECK(doc != nullptr && doc->root != nullptr) << "failed to parse inline XML string";
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700240 return doc;
241}
242
243std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(IAaptContext* context,
244 const StringPiece& str) {
245 std::unique_ptr<xml::XmlResource> doc = BuildXmlDom(str);
246 doc->file.name.package = context->GetCompilationPackage();
247 return doc;
248}
249
Shane Farmer0a5b2012017-06-22 12:24:12 -0700250ArtifactBuilder& ArtifactBuilder::SetName(const std::string& name) {
Shane Farmercb6c3f92017-11-27 13:19:36 -0800251 artifact_.name = name;
Shane Farmer0a5b2012017-06-22 12:24:12 -0700252 return *this;
253}
254
Shane Farmer78c43d72017-12-04 09:08:38 -0800255ArtifactBuilder& ArtifactBuilder::SetVersion(int version) {
256 artifact_.version = version;
257 return *this;
258}
259
Shane Farmercb6c3f92017-11-27 13:19:36 -0800260ArtifactBuilder& ArtifactBuilder::AddAbi(configuration::Abi abi) {
261 artifact_.abis.push_back(abi);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700262 return *this;
263}
264
Shane Farmercb6c3f92017-11-27 13:19:36 -0800265ArtifactBuilder& ArtifactBuilder::AddDensity(const ConfigDescription& density) {
266 artifact_.screen_densities.push_back(density);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700267 return *this;
268}
269
Shane Farmercb6c3f92017-11-27 13:19:36 -0800270ArtifactBuilder& ArtifactBuilder::AddLocale(const ConfigDescription& locale) {
271 artifact_.locales.push_back(locale);
Shane Farmer0a5b2012017-06-22 12:24:12 -0700272 return *this;
273}
274
Shane Farmercb6c3f92017-11-27 13:19:36 -0800275ArtifactBuilder& ArtifactBuilder::SetAndroidSdk(int min_sdk) {
276 artifact_.android_sdk = {AndroidSdk::ForMinSdk(min_sdk)};
Shane Farmerefe45392017-08-21 14:39:28 -0700277 return *this;
278}
279
Shane Farmercb6c3f92017-11-27 13:19:36 -0800280configuration::OutputArtifact ArtifactBuilder::Build() {
Shane Farmer0a5b2012017-06-22 12:24:12 -0700281 return artifact_;
282}
283
Shane Farmer78c43d72017-12-04 09:08:38 -0800284PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddAbiGroup(
285 const std::string& label, std::vector<configuration::Abi> abis) {
286 return AddGroup(label, &config_.abi_groups, std::move(abis));
287}
288
289PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddDensityGroup(
290 const std::string& label, std::vector<std::string> densities) {
291 std::vector<ConfigDescription> configs;
292 for (const auto& density : densities) {
293 configs.push_back(test::ParseConfigOrDie(density));
294 }
295 return AddGroup(label, &config_.screen_density_groups, configs);
296}
297
298PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddLocaleGroup(
299 const std::string& label, std::vector<std::string> locales) {
300 std::vector<ConfigDescription> configs;
301 for (const auto& locale : locales) {
302 configs.push_back(test::ParseConfigOrDie(locale));
303 }
304 return AddGroup(label, &config_.locale_groups, configs);
305}
306
307PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddDeviceFeatureGroup(
308 const std::string& label) {
309 return AddGroup(label, &config_.device_feature_groups);
310}
311
312PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddGlTextureGroup(
313 const std::string& label) {
314 return AddGroup(label, &config_.gl_texture_groups);
315}
316
317PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddAndroidSdk(
318 std::string label, int min_sdk) {
319 config_.android_sdks[label] = AndroidSdk::ForMinSdk(min_sdk);
320 return *this;
321}
322
323PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddArtifact(
324 configuration::ConfiguredArtifact artifact) {
325 config_.artifacts.push_back(std::move(artifact));
326 return *this;
327}
328
329configuration::PostProcessingConfiguration PostProcessingConfigurationBuilder::Build() {
330 return config_;
331}
332
Adam Lesinskiefeb7af2017-08-02 14:57:43 -0700333} // namespace test
334} // namespace aapt