• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
19 #include "android-base/logging.h"
20 #include "androidfw/StringPiece.h"
21 
22 #include "io/StringStream.h"
23 #include "test/Common.h"
24 #include "util/Util.h"
25 
26 using ::aapt::configuration::Abi;
27 using ::aapt::configuration::AndroidSdk;
28 using ::aapt::configuration::ConfiguredArtifact;
29 using ::aapt::configuration::GetOrCreateGroup;
30 using ::aapt::io::StringInputStream;
31 using ::android::ConfigDescription;
32 using ::android::StringPiece;
33 
34 namespace aapt {
35 namespace test {
36 
AddSimple(const StringPiece & name,const ResourceId & id)37 ResourceTableBuilder& ResourceTableBuilder::AddSimple(const StringPiece& name,
38                                                       const ResourceId& id) {
39   return AddValue(name, id, util::make_unique<Id>());
40 }
41 
AddSimple(const StringPiece & name,const ConfigDescription & config,const ResourceId & id)42 ResourceTableBuilder& 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 
AddReference(const StringPiece & name,const StringPiece & ref)48 ResourceTableBuilder& ResourceTableBuilder::AddReference(const StringPiece& name,
49                                                          const StringPiece& ref) {
50   return AddReference(name, {}, ref);
51 }
52 
AddReference(const StringPiece & name,const ResourceId & id,const StringPiece & ref)53 ResourceTableBuilder& 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 
AddString(const StringPiece & name,const StringPiece & str)59 ResourceTableBuilder& ResourceTableBuilder::AddString(const StringPiece& name,
60                                                       const StringPiece& str) {
61   return AddString(name, {}, str);
62 }
63 
AddString(const StringPiece & name,const ResourceId & id,const StringPiece & str)64 ResourceTableBuilder& 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 
AddString(const StringPiece & name,const ResourceId & id,const ConfigDescription & config,const StringPiece & str)69 ResourceTableBuilder& 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 
AddFileReference(const StringPiece & name,const StringPiece & path,io::IFile * file)75 ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name,
76                                                              const StringPiece& path,
77                                                              io::IFile* file) {
78   return AddFileReference(name, {}, path, file);
79 }
80 
AddFileReference(const StringPiece & name,const ResourceId & id,const StringPiece & path,io::IFile * file)81 ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name,
82                                                              const ResourceId& id,
83                                                              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));
88 }
89 
AddFileReference(const StringPiece & name,const StringPiece & path,const ConfigDescription & config,io::IFile * file)90 ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name,
91                                                              const StringPiece& path,
92                                                              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));
97 }
98 
AddValue(const StringPiece & name,std::unique_ptr<Value> value)99 ResourceTableBuilder& ResourceTableBuilder::AddValue(const StringPiece& name,
100                                                      std::unique_ptr<Value> value) {
101   return AddValue(name, {}, std::move(value));
102 }
103 
AddValue(const StringPiece & name,const ResourceId & id,std::unique_ptr<Value> value)104 ResourceTableBuilder& ResourceTableBuilder::AddValue(const StringPiece& name, const ResourceId& id,
105                                                      std::unique_ptr<Value> value) {
106   return AddValue(name, {}, id, std::move(value));
107 }
108 
AddValue(const StringPiece & name,const ConfigDescription & config,const ResourceId & id,std::unique_ptr<Value> value)109 ResourceTableBuilder& 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);
114   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()));
121   return *this;
122 }
123 
SetSymbolState(const StringPiece & name,const ResourceId & id,Visibility::Level level,bool allow_new)124 ResourceTableBuilder& ResourceTableBuilder::SetSymbolState(const StringPiece& name,
125                                                            const ResourceId& id,
126                                                            Visibility::Level level,
127                                                            bool allow_new) {
128   ResourceName res_name = ParseNameOrDie(name);
129   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()));
136   return *this;
137 }
138 
SetOverlayable(const StringPiece & name,const OverlayableItem & overlayable)139 ResourceTableBuilder& ResourceTableBuilder::SetOverlayable(const StringPiece& name,
140                                                            const OverlayableItem& overlayable) {
141 
142   ResourceName res_name = ParseNameOrDie(name);
143   CHECK(table_->AddResource(
144       NewResourceBuilder(res_name).SetOverlayable(overlayable).SetAllowMangled(true).Build(),
145       GetDiagnostics()));
146   return *this;
147 }
148 
Add(NewResource && res)149 ResourceTableBuilder& ResourceTableBuilder::Add(NewResource&& res) {
150   CHECK(table_->AddResource(std::move(res), GetDiagnostics()));
151   return *this;
152 }
153 
string_pool()154 StringPool* ResourceTableBuilder::string_pool() {
155   return &table_->string_pool;
156 }
157 
Build()158 std::unique_ptr<ResourceTable> ResourceTableBuilder::Build() {
159   return std::move(table_);
160 }
161 
BuildReference(const StringPiece & ref,const std::optional<ResourceId> & id)162 std::unique_ptr<Reference> BuildReference(const StringPiece& ref,
163                                           const std::optional<ResourceId>& id) {
164   std::unique_ptr<Reference> reference = util::make_unique<Reference>(ParseNameOrDie(ref));
165   reference->id = id;
166   return reference;
167 }
168 
BuildPrimitive(uint8_t type,uint32_t data)169 std::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 
AttributeBuilder()177 AttributeBuilder::AttributeBuilder()
178     : attr_(util::make_unique<Attribute>(android::ResTable_map::TYPE_ANY)) {
179 }
180 
SetTypeMask(uint32_t typeMask)181 AttributeBuilder& AttributeBuilder::SetTypeMask(uint32_t typeMask) {
182   attr_->type_mask = typeMask;
183   return *this;
184 }
185 
SetWeak(bool weak)186 AttributeBuilder& AttributeBuilder::SetWeak(bool weak) {
187   attr_->SetWeak(weak);
188   return *this;
189 }
190 
AddItem(const StringPiece & name,uint32_t value)191 AttributeBuilder& 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 
Build()197 std::unique_ptr<Attribute> AttributeBuilder::Build() {
198   return std::move(attr_);
199 }
200 
SetParent(const StringPiece & str)201 StyleBuilder& StyleBuilder::SetParent(const StringPiece& str) {
202   style_->parent = Reference(ParseNameOrDie(str));
203   return *this;
204 }
205 
AddItem(const StringPiece & str,std::unique_ptr<Item> value)206 StyleBuilder& 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 
AddItem(const StringPiece & str,const ResourceId & id,std::unique_ptr<Item> value)211 StyleBuilder& 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 
Build()218 std::unique_ptr<Style> StyleBuilder::Build() {
219   return std::move(style_);
220 }
221 
AddItem(const StringPiece & str,const std::optional<ResourceId> & id)222 StyleableBuilder& StyleableBuilder::AddItem(const StringPiece& str,
223                                             const std::optional<ResourceId>& id) {
224   styleable_->entries.push_back(Reference(ParseNameOrDie(str)));
225   styleable_->entries.back().id = id;
226   return *this;
227 }
228 
Build()229 std::unique_ptr<Styleable> StyleableBuilder::Build() {
230   return std::move(styleable_);
231 }
232 
BuildXmlDom(const StringPiece & str)233 std::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;
238   std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, &diag, Source("test.xml"));
239   CHECK(doc != nullptr && doc->root != nullptr) << "failed to parse inline XML string";
240   return doc;
241 }
242 
BuildXmlDomForPackageName(IAaptContext * context,const StringPiece & str)243 std::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 
SetName(const std::string & name)250 ArtifactBuilder& ArtifactBuilder::SetName(const std::string& name) {
251   artifact_.name = name;
252   return *this;
253 }
254 
SetVersion(int version)255 ArtifactBuilder& ArtifactBuilder::SetVersion(int version) {
256   artifact_.version = version;
257   return *this;
258 }
259 
AddAbi(configuration::Abi abi)260 ArtifactBuilder& ArtifactBuilder::AddAbi(configuration::Abi abi) {
261   artifact_.abis.push_back(abi);
262   return *this;
263 }
264 
AddDensity(const ConfigDescription & density)265 ArtifactBuilder& ArtifactBuilder::AddDensity(const ConfigDescription& density) {
266   artifact_.screen_densities.push_back(density);
267   return *this;
268 }
269 
AddLocale(const ConfigDescription & locale)270 ArtifactBuilder& ArtifactBuilder::AddLocale(const ConfigDescription& locale) {
271   artifact_.locales.push_back(locale);
272   return *this;
273 }
274 
SetAndroidSdk(int min_sdk)275 ArtifactBuilder& ArtifactBuilder::SetAndroidSdk(int min_sdk) {
276   artifact_.android_sdk = {AndroidSdk::ForMinSdk(min_sdk)};
277   return *this;
278 }
279 
Build()280 configuration::OutputArtifact ArtifactBuilder::Build() {
281   return artifact_;
282 }
283 
AddAbiGroup(const std::string & label,std::vector<configuration::Abi> abis)284 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddAbiGroup(
285     const std::string& label, std::vector<configuration::Abi> abis) {
286   return AddGroup(label, &config_.abi_groups, std::move(abis));
287 }
288 
AddDensityGroup(const std::string & label,std::vector<std::string> densities)289 PostProcessingConfigurationBuilder& 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 
AddLocaleGroup(const std::string & label,std::vector<std::string> locales)298 PostProcessingConfigurationBuilder& 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 
AddDeviceFeatureGroup(const std::string & label)307 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddDeviceFeatureGroup(
308     const std::string& label) {
309   return AddGroup(label, &config_.device_feature_groups);
310 }
311 
AddGlTextureGroup(const std::string & label)312 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddGlTextureGroup(
313     const std::string& label) {
314   return AddGroup(label, &config_.gl_texture_groups);
315 }
316 
AddAndroidSdk(std::string label,int min_sdk)317 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddAndroidSdk(
318     std::string label, int min_sdk) {
319   config_.android_sdks[label] = AndroidSdk::ForMinSdk(min_sdk);
320   return *this;
321 }
322 
AddArtifact(configuration::ConfiguredArtifact artifact)323 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddArtifact(
324     configuration::ConfiguredArtifact artifact) {
325   config_.artifacts.push_back(std::move(artifact));
326   return *this;
327 }
328 
Build()329 configuration::PostProcessingConfiguration PostProcessingConfigurationBuilder::Build() {
330   return config_;
331 }
332 
333 }  // namespace test
334 }  // namespace aapt
335