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