• 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 Maybe<ResourceId> & id)162 std::unique_ptr<Reference> BuildReference(const StringPiece& ref, const Maybe<ResourceId>& id) {
163   std::unique_ptr<Reference> reference = util::make_unique<Reference>(ParseNameOrDie(ref));
164   reference->id = id;
165   return reference;
166 }
167 
BuildPrimitive(uint8_t type,uint32_t data)168 std::unique_ptr<BinaryPrimitive> BuildPrimitive(uint8_t type, uint32_t data) {
169   android::Res_value value = {};
170   value.size = sizeof(value);
171   value.dataType = type;
172   value.data = data;
173   return util::make_unique<BinaryPrimitive>(value);
174 }
175 
AttributeBuilder()176 AttributeBuilder::AttributeBuilder()
177     : attr_(util::make_unique<Attribute>(android::ResTable_map::TYPE_ANY)) {
178 }
179 
SetTypeMask(uint32_t typeMask)180 AttributeBuilder& AttributeBuilder::SetTypeMask(uint32_t typeMask) {
181   attr_->type_mask = typeMask;
182   return *this;
183 }
184 
SetWeak(bool weak)185 AttributeBuilder& AttributeBuilder::SetWeak(bool weak) {
186   attr_->SetWeak(weak);
187   return *this;
188 }
189 
AddItem(const StringPiece & name,uint32_t value)190 AttributeBuilder& AttributeBuilder::AddItem(const StringPiece& name, uint32_t value) {
191   attr_->symbols.push_back(
192       Attribute::Symbol{Reference(ResourceName({}, ResourceType::kId, name)), value});
193   return *this;
194 }
195 
Build()196 std::unique_ptr<Attribute> AttributeBuilder::Build() {
197   return std::move(attr_);
198 }
199 
SetParent(const StringPiece & str)200 StyleBuilder& StyleBuilder::SetParent(const StringPiece& str) {
201   style_->parent = Reference(ParseNameOrDie(str));
202   return *this;
203 }
204 
AddItem(const StringPiece & str,std::unique_ptr<Item> value)205 StyleBuilder& StyleBuilder::AddItem(const StringPiece& str, std::unique_ptr<Item> value) {
206   style_->entries.push_back(Style::Entry{Reference(ParseNameOrDie(str)), std::move(value)});
207   return *this;
208 }
209 
AddItem(const StringPiece & str,const ResourceId & id,std::unique_ptr<Item> value)210 StyleBuilder& StyleBuilder::AddItem(const StringPiece& str, const ResourceId& id,
211                                     std::unique_ptr<Item> value) {
212   AddItem(str, std::move(value));
213   style_->entries.back().key.id = id;
214   return *this;
215 }
216 
Build()217 std::unique_ptr<Style> StyleBuilder::Build() {
218   return std::move(style_);
219 }
220 
AddItem(const StringPiece & str,const Maybe<ResourceId> & id)221 StyleableBuilder& StyleableBuilder::AddItem(const StringPiece& str, const Maybe<ResourceId>& id) {
222   styleable_->entries.push_back(Reference(ParseNameOrDie(str)));
223   styleable_->entries.back().id = id;
224   return *this;
225 }
226 
Build()227 std::unique_ptr<Styleable> StyleableBuilder::Build() {
228   return std::move(styleable_);
229 }
230 
BuildXmlDom(const StringPiece & str)231 std::unique_ptr<xml::XmlResource> BuildXmlDom(const StringPiece& str) {
232   std::string input = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
233   input.append(str.data(), str.size());
234   StringInputStream in(input);
235   StdErrDiagnostics diag;
236   std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, &diag, Source("test.xml"));
237   CHECK(doc != nullptr && doc->root != nullptr) << "failed to parse inline XML string";
238   return doc;
239 }
240 
BuildXmlDomForPackageName(IAaptContext * context,const StringPiece & str)241 std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(IAaptContext* context,
242                                                             const StringPiece& str) {
243   std::unique_ptr<xml::XmlResource> doc = BuildXmlDom(str);
244   doc->file.name.package = context->GetCompilationPackage();
245   return doc;
246 }
247 
SetName(const std::string & name)248 ArtifactBuilder& ArtifactBuilder::SetName(const std::string& name) {
249   artifact_.name = name;
250   return *this;
251 }
252 
SetVersion(int version)253 ArtifactBuilder& ArtifactBuilder::SetVersion(int version) {
254   artifact_.version = version;
255   return *this;
256 }
257 
AddAbi(configuration::Abi abi)258 ArtifactBuilder& ArtifactBuilder::AddAbi(configuration::Abi abi) {
259   artifact_.abis.push_back(abi);
260   return *this;
261 }
262 
AddDensity(const ConfigDescription & density)263 ArtifactBuilder& ArtifactBuilder::AddDensity(const ConfigDescription& density) {
264   artifact_.screen_densities.push_back(density);
265   return *this;
266 }
267 
AddLocale(const ConfigDescription & locale)268 ArtifactBuilder& ArtifactBuilder::AddLocale(const ConfigDescription& locale) {
269   artifact_.locales.push_back(locale);
270   return *this;
271 }
272 
SetAndroidSdk(int min_sdk)273 ArtifactBuilder& ArtifactBuilder::SetAndroidSdk(int min_sdk) {
274   artifact_.android_sdk = {AndroidSdk::ForMinSdk(min_sdk)};
275   return *this;
276 }
277 
Build()278 configuration::OutputArtifact ArtifactBuilder::Build() {
279   return artifact_;
280 }
281 
AddAbiGroup(const std::string & label,std::vector<configuration::Abi> abis)282 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddAbiGroup(
283     const std::string& label, std::vector<configuration::Abi> abis) {
284   return AddGroup(label, &config_.abi_groups, std::move(abis));
285 }
286 
AddDensityGroup(const std::string & label,std::vector<std::string> densities)287 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddDensityGroup(
288     const std::string& label, std::vector<std::string> densities) {
289   std::vector<ConfigDescription> configs;
290   for (const auto& density : densities) {
291     configs.push_back(test::ParseConfigOrDie(density));
292   }
293   return AddGroup(label, &config_.screen_density_groups, configs);
294 }
295 
AddLocaleGroup(const std::string & label,std::vector<std::string> locales)296 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddLocaleGroup(
297     const std::string& label, std::vector<std::string> locales) {
298   std::vector<ConfigDescription> configs;
299   for (const auto& locale : locales) {
300     configs.push_back(test::ParseConfigOrDie(locale));
301   }
302   return AddGroup(label, &config_.locale_groups, configs);
303 }
304 
AddDeviceFeatureGroup(const std::string & label)305 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddDeviceFeatureGroup(
306     const std::string& label) {
307   return AddGroup(label, &config_.device_feature_groups);
308 }
309 
AddGlTextureGroup(const std::string & label)310 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddGlTextureGroup(
311     const std::string& label) {
312   return AddGroup(label, &config_.gl_texture_groups);
313 }
314 
AddAndroidSdk(std::string label,int min_sdk)315 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddAndroidSdk(
316     std::string label, int min_sdk) {
317   config_.android_sdks[label] = AndroidSdk::ForMinSdk(min_sdk);
318   return *this;
319 }
320 
AddArtifact(configuration::ConfiguredArtifact artifact)321 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddArtifact(
322     configuration::ConfiguredArtifact artifact) {
323   config_.artifacts.push_back(std::move(artifact));
324   return *this;
325 }
326 
Build()327 configuration::PostProcessingConfiguration PostProcessingConfigurationBuilder::Build() {
328   return config_;
329 }
330 
331 }  // namespace test
332 }  // namespace aapt
333