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& AddItem(android::StringPiece name, uint32_t value);
120   std::unique_ptr<Attribute> Build();
121 
122  private:
123   DISALLOW_COPY_AND_ASSIGN(AttributeBuilder);
124 
125   std::unique_ptr<Attribute> attr_;
126 };
127 
128 class StyleBuilder {
129  public:
130   StyleBuilder() = default;
131   StyleBuilder& SetParent(android::StringPiece str);
132   StyleBuilder& AddItem(android::StringPiece str, std::unique_ptr<Item> value);
133   StyleBuilder& AddItem(android::StringPiece str, const ResourceId& id,
134                         std::unique_ptr<Item> value);
135   std::unique_ptr<Style> Build();
136 
137  private:
138   DISALLOW_COPY_AND_ASSIGN(StyleBuilder);
139 
140   std::unique_ptr<Style> style_ = util::make_unique<Style>();
141 };
142 
143 class StyleableBuilder {
144  public:
145   StyleableBuilder() = default;
146   StyleableBuilder& AddItem(android::StringPiece str, const std::optional<ResourceId>& id = {});
147   std::unique_ptr<Styleable> Build();
148 
149  private:
150   DISALLOW_COPY_AND_ASSIGN(StyleableBuilder);
151 
152   std::unique_ptr<Styleable> styleable_ = util::make_unique<Styleable>();
153 };
154 
155 std::unique_ptr<xml::XmlResource> BuildXmlDom(android::StringPiece str);
156 std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(IAaptContext* context,
157                                                             android::StringPiece str);
158 
159 class ArtifactBuilder {
160  public:
161   ArtifactBuilder() = default;
162 
163   ArtifactBuilder& SetName(const std::string& name);
164   ArtifactBuilder& SetVersion(int version);
165   ArtifactBuilder& AddAbi(configuration::Abi abi);
166   ArtifactBuilder& AddDensity(const android::ConfigDescription& density);
167   ArtifactBuilder& AddLocale(const android::ConfigDescription& locale);
168   ArtifactBuilder& SetAndroidSdk(int min_sdk);
169   configuration::OutputArtifact Build();
170 
171  private:
172   DISALLOW_COPY_AND_ASSIGN(ArtifactBuilder);
173 
174   configuration::OutputArtifact artifact_;
175 };
176 
177 class PostProcessingConfigurationBuilder {
178  public:
179   PostProcessingConfigurationBuilder() = default;
180 
181   PostProcessingConfigurationBuilder& AddAbiGroup(const std::string& label,
182                                                   std::vector<configuration::Abi> abis = {});
183   PostProcessingConfigurationBuilder& AddDensityGroup(const std::string& label,
184                                                       std::vector<std::string> densities = {});
185   PostProcessingConfigurationBuilder& AddLocaleGroup(const std::string& label,
186                                                      std::vector<std::string> locales = {});
187   PostProcessingConfigurationBuilder& AddDeviceFeatureGroup(const std::string& label);
188   PostProcessingConfigurationBuilder& AddGlTextureGroup(const std::string& label);
189   PostProcessingConfigurationBuilder& AddAndroidSdk(std::string label, int min_sdk);
190   PostProcessingConfigurationBuilder& AddArtifact(configuration::ConfiguredArtifact artrifact);
191 
192   configuration::PostProcessingConfiguration Build();
193 
194  private:
195   template <typename T>
196   inline PostProcessingConfigurationBuilder& AddGroup(const std::string& label,
197                                                       configuration::Group<T>* group,
198                                                       std::vector<T> to_add = {}) {
199     auto& values = GetOrCreateGroup(label, group);
200     values.insert(std::begin(values), std::begin(to_add), std::end(to_add));
201     return *this;
202   }
203 
204   configuration::PostProcessingConfiguration config_;
205 };
206 
207 class ConfigDescriptionBuilder {
208  public:
209   ConfigDescriptionBuilder() = default;
210 
setMcc(uint16_t mcc)211   ConfigDescriptionBuilder& setMcc(uint16_t mcc) {
212     config_.mcc = mcc;
213     return *this;
214   }
setMnc(uint16_t mnc)215   ConfigDescriptionBuilder& setMnc(uint16_t mnc) {
216     config_.mnc = mnc;
217     return *this;
218   }
setLanguage(uint16_t language)219   ConfigDescriptionBuilder& setLanguage(uint16_t language) {
220     config_.language[0] = language >> 8;
221     config_.language[1] = language & 0xff;
222     return *this;
223   }
setCountry(uint16_t country)224   ConfigDescriptionBuilder& setCountry(uint16_t country) {
225     config_.country[0] = country >> 8;
226     config_.country[1] = country & 0xff;
227     return *this;
228   }
setOrientation(uint8_t orientation)229   ConfigDescriptionBuilder& setOrientation(uint8_t orientation) {
230     config_.orientation = orientation;
231     return *this;
232   }
setTouchscreen(uint8_t touchscreen)233   ConfigDescriptionBuilder& setTouchscreen(uint8_t touchscreen) {
234     config_.touchscreen = touchscreen;
235     return *this;
236   }
setDensity(uint16_t density)237   ConfigDescriptionBuilder& setDensity(uint16_t density) {
238     config_.density = density;
239     return *this;
240   }
setKeyboard(uint8_t keyboard)241   ConfigDescriptionBuilder& setKeyboard(uint8_t keyboard) {
242     config_.keyboard = keyboard;
243     return *this;
244   }
setNavigation(uint8_t navigation)245   ConfigDescriptionBuilder& setNavigation(uint8_t navigation) {
246     config_.navigation = navigation;
247     return *this;
248   }
setInputFlags(uint8_t inputFlags)249   ConfigDescriptionBuilder& setInputFlags(uint8_t inputFlags) {
250     config_.inputFlags = inputFlags;
251     return *this;
252   }
setInputPad0(uint8_t inputPad0)253   ConfigDescriptionBuilder& setInputPad0(uint8_t inputPad0) {
254     config_.inputFieldPad0 = inputPad0;
255     return *this;
256   }
setGrammaticalInflection(uint8_t value)257   ConfigDescriptionBuilder& setGrammaticalInflection(uint8_t value) {
258     config_.grammaticalInflection = value;
259     return *this;
260   }
setScreenWidth(uint16_t screenWidth)261   ConfigDescriptionBuilder& setScreenWidth(uint16_t screenWidth) {
262     config_.screenWidth = screenWidth;
263     return *this;
264   }
setScreenHeight(uint16_t screenHeight)265   ConfigDescriptionBuilder& setScreenHeight(uint16_t screenHeight) {
266     config_.screenHeight = screenHeight;
267     return *this;
268   }
setSdkVersion(uint16_t sdkVersion)269   ConfigDescriptionBuilder& setSdkVersion(uint16_t sdkVersion) {
270     config_.sdkVersion = sdkVersion;
271     return *this;
272   }
setMinorVersion(uint16_t minorVersion)273   ConfigDescriptionBuilder& setMinorVersion(uint16_t minorVersion) {
274     config_.minorVersion = minorVersion;
275     return *this;
276   }
setScreenLayout(uint8_t screenLayout)277   ConfigDescriptionBuilder& setScreenLayout(uint8_t screenLayout) {
278     config_.screenLayout = screenLayout;
279     return *this;
280   }
setUiMode(uint8_t uiMode)281   ConfigDescriptionBuilder& setUiMode(uint8_t uiMode) {
282     config_.uiMode = uiMode;
283     return *this;
284   }
setSmallestScreenWidthDp(uint16_t smallestScreenWidthDp)285   ConfigDescriptionBuilder& setSmallestScreenWidthDp(uint16_t smallestScreenWidthDp) {
286     config_.smallestScreenWidthDp = smallestScreenWidthDp;
287     return *this;
288   }
setScreenWidthDp(uint16_t screenWidthDp)289   ConfigDescriptionBuilder& setScreenWidthDp(uint16_t screenWidthDp) {
290     config_.screenWidthDp = screenWidthDp;
291     return *this;
292   }
setScreenHeightDp(uint16_t screenHeightDp)293   ConfigDescriptionBuilder& setScreenHeightDp(uint16_t screenHeightDp) {
294     config_.screenHeightDp = screenHeightDp;
295     return *this;
296   }
setScreenLayout2(uint8_t screenLayout2)297   ConfigDescriptionBuilder& setScreenLayout2(uint8_t screenLayout2) {
298     config_.screenLayout2 = screenLayout2;
299     return *this;
300   }
setColorMode(uint8_t colorMode)301   ConfigDescriptionBuilder& setColorMode(uint8_t colorMode) {
302     config_.colorMode = colorMode;
303     return *this;
304   }
setScreenConfigPad2(uint16_t screenConfigPad2)305   ConfigDescriptionBuilder& setScreenConfigPad2(uint16_t screenConfigPad2) {
306     config_.screenConfigPad2 = screenConfigPad2;
307     return *this;
308   }
Build()309   android::ConfigDescription Build() {
310     return config_;
311   }
312 
313  private:
314   android::ConfigDescription config_;
315 };
316 
317 }  // namespace test
318 }  // namespace aapt
319 
320 #endif /* AAPT_TEST_BUILDERS_H */
321