1 /*
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_TEST_BUILDERS_H
18 #define AAPT_TEST_BUILDERS_H
19 
20 #include <memory>
21 
22 #include "android-base/macros.h"
23 #include "androidfw/ConfigDescription.h"
24 
25 #include "Resource.h"
26 #include "ResourceTable.h"
27 #include "ResourceValues.h"
28 #include "configuration/ConfigurationParser.h"
29 #include "configuration/ConfigurationParser.internal.h"
30 #include "process/IResourceTableConsumer.h"
31 #include "test/Common.h"
32 #include "xml/XmlDom.h"
33 
34 namespace aapt {
35 namespace test {
36 
37 class ResourceTableBuilder {
38  public:
39   ResourceTableBuilder() = default;
40 
41   ResourceTableBuilder& AddSimple(android::StringPiece name, const ResourceId& id = {});
42   ResourceTableBuilder& AddSimple(android::StringPiece name,
43                                   const android::ConfigDescription& config,
44                                   const ResourceId& id = {});
45   ResourceTableBuilder& AddReference(android::StringPiece name, android::StringPiece ref);
46   ResourceTableBuilder& AddReference(android::StringPiece name, const ResourceId& id,
47                                      android::StringPiece ref);
48   ResourceTableBuilder& AddString(android::StringPiece name, android::StringPiece str);
49   ResourceTableBuilder& AddString(android::StringPiece name, const ResourceId& id,
50                                   android::StringPiece str);
51   ResourceTableBuilder& AddString(android::StringPiece name, const ResourceId& id,
52                                   const android::ConfigDescription& config,
53                                   android::StringPiece str);
54   ResourceTableBuilder& AddFileReference(android::StringPiece name, android::StringPiece path,
55                                          io::IFile* file = nullptr);
56   ResourceTableBuilder& AddFileReference(android::StringPiece name, const ResourceId& id,
57                                          android::StringPiece path, io::IFile* file = nullptr);
58   ResourceTableBuilder& AddFileReference(android::StringPiece name, android::StringPiece path,
59                                          const android::ConfigDescription& config,
60                                          io::IFile* file = nullptr);
61   ResourceTableBuilder& AddValue(android::StringPiece name, std::unique_ptr<Value> value);
62   ResourceTableBuilder& AddValue(android::StringPiece name, const ResourceId& id,
63                                  std::unique_ptr<Value> value);
64   ResourceTableBuilder& AddValue(android::StringPiece name,
65                                  const android::ConfigDescription& config, const ResourceId& id,
66                                  std::unique_ptr<Value> value);
67   ResourceTableBuilder& SetSymbolState(android::StringPiece name, const ResourceId& id,
68                                        Visibility::Level level, bool allow_new = false);
69   ResourceTableBuilder& SetOverlayable(android::StringPiece name,
70                                        const OverlayableItem& overlayable);
71   ResourceTableBuilder& Add(NewResource&& res);
72 
73   android::StringPool* string_pool();
74   std::unique_ptr<ResourceTable> Build();
75 
76  private:
77   DISALLOW_COPY_AND_ASSIGN(ResourceTableBuilder);
78 
79   std::unique_ptr<ResourceTable> table_ = util::make_unique<ResourceTable>();
80 };
81 
82 std::unique_ptr<Reference> BuildReference(android::StringPiece ref,
83                                           const std::optional<ResourceId>& id = {});
84 std::unique_ptr<BinaryPrimitive> BuildPrimitive(uint8_t type, uint32_t data);
85 
86 template <typename T>
87 class ValueBuilder {
88  public:
89   template <typename... Args>
ValueBuilder(Args &&...args)90   explicit ValueBuilder(Args&&... args) : value_(new T{std::forward<Args>(args)...}) {
91   }
92 
93   template <typename... Args>
SetSource(Args &&...args)94   ValueBuilder& SetSource(Args&&... args) {
95     value_->SetSource(android::Source{std::forward<Args>(args)...});
96     return *this;
97   }
98 
SetComment(android::StringPiece str)99   ValueBuilder& SetComment(android::StringPiece str) {
100     value_->SetComment(str);
101     return *this;
102   }
103 
Build()104   std::unique_ptr<Value> Build() {
105     return std::move(value_);
106   }
107 
108  private:
109   DISALLOW_COPY_AND_ASSIGN(ValueBuilder);
110 
111   std::unique_ptr<Value> value_;
112 };
113 
114 class AttributeBuilder {
115  public:
116   AttributeBuilder();
117   AttributeBuilder& SetTypeMask(uint32_t typeMask);
118   AttributeBuilder& SetWeak(bool weak);
119   AttributeBuilder& SetComment(android::StringPiece comment);
120   AttributeBuilder& AddItem(android::StringPiece name, uint32_t value);
121   AttributeBuilder& AddItemWithComment(android::StringPiece name, uint32_t value,
122                                        android::StringPiece comment);
123   std::unique_ptr<Attribute> Build();
124 
125  private:
126   DISALLOW_COPY_AND_ASSIGN(AttributeBuilder);
127 
128   std::unique_ptr<Attribute> attr_;
129 };
130 
131 class StyleBuilder {
132  public:
133   StyleBuilder() = default;
134   StyleBuilder& SetParent(android::StringPiece str);
135   StyleBuilder& AddItem(android::StringPiece str, std::unique_ptr<Item> value);
136   StyleBuilder& AddItem(android::StringPiece str, const ResourceId& id,
137                         std::unique_ptr<Item> value);
138   std::unique_ptr<Style> Build();
139 
140  private:
141   DISALLOW_COPY_AND_ASSIGN(StyleBuilder);
142 
143   std::unique_ptr<Style> style_ = util::make_unique<Style>();
144 };
145 
146 class StyleableBuilder {
147  public:
148   StyleableBuilder() = default;
149   StyleableBuilder& AddItem(android::StringPiece str, const std::optional<ResourceId>& id = {});
150   std::unique_ptr<Styleable> Build();
151 
152  private:
153   DISALLOW_COPY_AND_ASSIGN(StyleableBuilder);
154 
155   std::unique_ptr<Styleable> styleable_ = util::make_unique<Styleable>();
156 };
157 
158 std::unique_ptr<xml::XmlResource> BuildXmlDom(android::StringPiece str);
159 std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(IAaptContext* context,
160                                                             android::StringPiece str);
161 
162 class ArtifactBuilder {
163  public:
164   ArtifactBuilder() = default;
165 
166   ArtifactBuilder& SetName(const std::string& name);
167   ArtifactBuilder& SetVersion(int version);
168   ArtifactBuilder& AddAbi(configuration::Abi abi);
169   ArtifactBuilder& AddDensity(const android::ConfigDescription& density);
170   ArtifactBuilder& AddLocale(const android::ConfigDescription& locale);
171   ArtifactBuilder& SetAndroidSdk(int min_sdk);
172   configuration::OutputArtifact Build();
173 
174  private:
175   DISALLOW_COPY_AND_ASSIGN(ArtifactBuilder);
176 
177   configuration::OutputArtifact artifact_;
178 };
179 
180 class PostProcessingConfigurationBuilder {
181  public:
182   PostProcessingConfigurationBuilder() = default;
183 
184   PostProcessingConfigurationBuilder& AddAbiGroup(const std::string& label,
185                                                   std::vector<configuration::Abi> abis = {});
186   PostProcessingConfigurationBuilder& AddDensityGroup(const std::string& label,
187                                                       std::vector<std::string> densities = {});
188   PostProcessingConfigurationBuilder& AddLocaleGroup(const std::string& label,
189                                                      std::vector<std::string> locales = {});
190   PostProcessingConfigurationBuilder& AddDeviceFeatureGroup(const std::string& label);
191   PostProcessingConfigurationBuilder& AddGlTextureGroup(const std::string& label);
192   PostProcessingConfigurationBuilder& AddAndroidSdk(std::string label, int min_sdk);
193   PostProcessingConfigurationBuilder& AddArtifact(configuration::ConfiguredArtifact artrifact);
194 
195   configuration::PostProcessingConfiguration Build();
196 
197  private:
198   template <typename T>
199   inline PostProcessingConfigurationBuilder& AddGroup(const std::string& label,
200                                                       configuration::Group<T>* group,
201                                                       std::vector<T> to_add = {}) {
202     auto& values = GetOrCreateGroup(label, group);
203     values.insert(std::begin(values), std::begin(to_add), std::end(to_add));
204     return *this;
205   }
206 
207   configuration::PostProcessingConfiguration config_;
208 };
209 
210 class ConfigDescriptionBuilder {
211  public:
212   ConfigDescriptionBuilder() = default;
213 
setMcc(uint16_t mcc)214   ConfigDescriptionBuilder& setMcc(uint16_t mcc) {
215     config_.mcc = mcc;
216     return *this;
217   }
setMnc(uint16_t mnc)218   ConfigDescriptionBuilder& setMnc(uint16_t mnc) {
219     config_.mnc = mnc;
220     return *this;
221   }
setLanguage(uint16_t language)222   ConfigDescriptionBuilder& setLanguage(uint16_t language) {
223     config_.language[0] = language >> 8;
224     config_.language[1] = language & 0xff;
225     return *this;
226   }
setCountry(uint16_t country)227   ConfigDescriptionBuilder& setCountry(uint16_t country) {
228     config_.country[0] = country >> 8;
229     config_.country[1] = country & 0xff;
230     return *this;
231   }
setOrientation(uint8_t orientation)232   ConfigDescriptionBuilder& setOrientation(uint8_t orientation) {
233     config_.orientation = orientation;
234     return *this;
235   }
setTouchscreen(uint8_t touchscreen)236   ConfigDescriptionBuilder& setTouchscreen(uint8_t touchscreen) {
237     config_.touchscreen = touchscreen;
238     return *this;
239   }
setDensity(uint16_t density)240   ConfigDescriptionBuilder& setDensity(uint16_t density) {
241     config_.density = density;
242     return *this;
243   }
setKeyboard(uint8_t keyboard)244   ConfigDescriptionBuilder& setKeyboard(uint8_t keyboard) {
245     config_.keyboard = keyboard;
246     return *this;
247   }
setNavigation(uint8_t navigation)248   ConfigDescriptionBuilder& setNavigation(uint8_t navigation) {
249     config_.navigation = navigation;
250     return *this;
251   }
setInputFlags(uint8_t inputFlags)252   ConfigDescriptionBuilder& setInputFlags(uint8_t inputFlags) {
253     config_.inputFlags = inputFlags;
254     return *this;
255   }
setInputPad0(uint8_t inputPad0)256   ConfigDescriptionBuilder& setInputPad0(uint8_t inputPad0) {
257     config_.inputFieldPad0 = inputPad0;
258     return *this;
259   }
setGrammaticalInflection(uint8_t value)260   ConfigDescriptionBuilder& setGrammaticalInflection(uint8_t value) {
261     config_.grammaticalInflection = value;
262     return *this;
263   }
setScreenWidth(uint16_t screenWidth)264   ConfigDescriptionBuilder& setScreenWidth(uint16_t screenWidth) {
265     config_.screenWidth = screenWidth;
266     return *this;
267   }
setScreenHeight(uint16_t screenHeight)268   ConfigDescriptionBuilder& setScreenHeight(uint16_t screenHeight) {
269     config_.screenHeight = screenHeight;
270     return *this;
271   }
setSdkVersion(uint16_t sdkVersion)272   ConfigDescriptionBuilder& setSdkVersion(uint16_t sdkVersion) {
273     config_.sdkVersion = sdkVersion;
274     return *this;
275   }
setMinorVersion(uint16_t minorVersion)276   ConfigDescriptionBuilder& setMinorVersion(uint16_t minorVersion) {
277     config_.minorVersion = minorVersion;
278     return *this;
279   }
setScreenLayout(uint8_t screenLayout)280   ConfigDescriptionBuilder& setScreenLayout(uint8_t screenLayout) {
281     config_.screenLayout = screenLayout;
282     return *this;
283   }
setUiMode(uint8_t uiMode)284   ConfigDescriptionBuilder& setUiMode(uint8_t uiMode) {
285     config_.uiMode = uiMode;
286     return *this;
287   }
setSmallestScreenWidthDp(uint16_t smallestScreenWidthDp)288   ConfigDescriptionBuilder& setSmallestScreenWidthDp(uint16_t smallestScreenWidthDp) {
289     config_.smallestScreenWidthDp = smallestScreenWidthDp;
290     return *this;
291   }
setScreenWidthDp(uint16_t screenWidthDp)292   ConfigDescriptionBuilder& setScreenWidthDp(uint16_t screenWidthDp) {
293     config_.screenWidthDp = screenWidthDp;
294     return *this;
295   }
setScreenHeightDp(uint16_t screenHeightDp)296   ConfigDescriptionBuilder& setScreenHeightDp(uint16_t screenHeightDp) {
297     config_.screenHeightDp = screenHeightDp;
298     return *this;
299   }
setScreenLayout2(uint8_t screenLayout2)300   ConfigDescriptionBuilder& setScreenLayout2(uint8_t screenLayout2) {
301     config_.screenLayout2 = screenLayout2;
302     return *this;
303   }
setColorMode(uint8_t colorMode)304   ConfigDescriptionBuilder& setColorMode(uint8_t colorMode) {
305     config_.colorMode = colorMode;
306     return *this;
307   }
setScreenConfigPad2(uint16_t screenConfigPad2)308   ConfigDescriptionBuilder& setScreenConfigPad2(uint16_t screenConfigPad2) {
309     config_.screenConfigPad2 = screenConfigPad2;
310     return *this;
311   }
Build()312   android::ConfigDescription Build() {
313     return config_;
314   }
315 
316  private:
317   android::ConfigDescription config_;
318 };
319 
320 }  // namespace test
321 }  // namespace aapt
322 
323 #endif /* AAPT_TEST_BUILDERS_H */
324