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 37 ResourceTableBuilder& ResourceTableBuilder::SetPackageId(const StringPiece& package_name, 38 uint8_t id) { 39 ResourceTablePackage* package = table_->CreatePackage(package_name, id); 40 CHECK(package != nullptr); 41 return *this; 42 } 43 44 ResourceTableBuilder& ResourceTableBuilder::AddSimple(const StringPiece& name, 45 const ResourceId& id) { 46 return AddValue(name, id, util::make_unique<Id>()); 47 } 48 49 ResourceTableBuilder& ResourceTableBuilder::AddSimple(const StringPiece& name, 50 const ConfigDescription& config, 51 const ResourceId& id) { 52 return AddValue(name, config, id, util::make_unique<Id>()); 53 } 54 55 ResourceTableBuilder& ResourceTableBuilder::AddReference(const StringPiece& name, 56 const StringPiece& ref) { 57 return AddReference(name, {}, ref); 58 } 59 60 ResourceTableBuilder& ResourceTableBuilder::AddReference(const StringPiece& name, 61 const ResourceId& id, 62 const StringPiece& ref) { 63 return AddValue(name, id, util::make_unique<Reference>(ParseNameOrDie(ref))); 64 } 65 66 ResourceTableBuilder& ResourceTableBuilder::AddString(const StringPiece& name, 67 const StringPiece& str) { 68 return AddString(name, {}, str); 69 } 70 71 ResourceTableBuilder& ResourceTableBuilder::AddString(const StringPiece& name, const ResourceId& id, 72 const StringPiece& str) { 73 return AddValue(name, id, util::make_unique<String>(table_->string_pool.MakeRef(str))); 74 } 75 76 ResourceTableBuilder& ResourceTableBuilder::AddString(const StringPiece& name, const ResourceId& id, 77 const ConfigDescription& config, 78 const StringPiece& str) { 79 return AddValue(name, config, id, util::make_unique<String>(table_->string_pool.MakeRef(str))); 80 } 81 82 ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name, 83 const StringPiece& path, 84 io::IFile* file) { 85 return AddFileReference(name, {}, path, file); 86 } 87 88 ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name, 89 const ResourceId& id, 90 const StringPiece& path, 91 io::IFile* file) { 92 auto file_ref = util::make_unique<FileReference>(table_->string_pool.MakeRef(path)); 93 file_ref->file = file; 94 return AddValue(name, id, std::move(file_ref)); 95 } 96 97 ResourceTableBuilder& ResourceTableBuilder::AddFileReference(const StringPiece& name, 98 const StringPiece& path, 99 const ConfigDescription& config, 100 io::IFile* file) { 101 auto file_ref = util::make_unique<FileReference>(table_->string_pool.MakeRef(path)); 102 file_ref->file = file; 103 return AddValue(name, config, {}, std::move(file_ref)); 104 } 105 106 ResourceTableBuilder& ResourceTableBuilder::AddValue(const StringPiece& name, 107 std::unique_ptr<Value> value) { 108 return AddValue(name, {}, std::move(value)); 109 } 110 111 ResourceTableBuilder& ResourceTableBuilder::AddValue(const StringPiece& name, const ResourceId& id, 112 std::unique_ptr<Value> value) { 113 return AddValue(name, {}, id, std::move(value)); 114 } 115 116 ResourceTableBuilder& ResourceTableBuilder::AddValue(const StringPiece& name, 117 const ConfigDescription& config, 118 const ResourceId& id, 119 std::unique_ptr<Value> value) { 120 ResourceName res_name = ParseNameOrDie(name); 121 CHECK(table_->AddResourceWithIdMangled(res_name, id, config, {}, std::move(value), 122 GetDiagnostics())); 123 return *this; 124 } 125 126 ResourceTableBuilder& ResourceTableBuilder::SetSymbolState(const StringPiece& name, 127 const ResourceId& id, 128 Visibility::Level level, 129 bool allow_new) { 130 ResourceName res_name = ParseNameOrDie(name); 131 Visibility visibility; 132 visibility.level = level; 133 CHECK(table_->SetVisibilityWithIdMangled(res_name, visibility, id, GetDiagnostics())); 134 CHECK(table_->SetAllowNewMangled(res_name, AllowNew{}, GetDiagnostics())); 135 return *this; 136 } 137 138 ResourceTableBuilder& ResourceTableBuilder::SetOverlayable(const StringPiece& name, 139 const OverlayableItem& overlayable) { 140 141 ResourceName res_name = ParseNameOrDie(name); 142 CHECK(table_->SetOverlayable(res_name, overlayable, GetDiagnostics())); 143 return *this; 144 } 145 146 StringPool* ResourceTableBuilder::string_pool() { 147 return &table_->string_pool; 148 } 149 150 std::unique_ptr<ResourceTable> ResourceTableBuilder::Build() { 151 return std::move(table_); 152 } 153 154 std::unique_ptr<Reference> BuildReference(const StringPiece& ref, const Maybe<ResourceId>& id) { 155 std::unique_ptr<Reference> reference = util::make_unique<Reference>(ParseNameOrDie(ref)); 156 reference->id = id; 157 return reference; 158 } 159 160 std::unique_ptr<BinaryPrimitive> BuildPrimitive(uint8_t type, uint32_t data) { 161 android::Res_value value = {}; 162 value.size = sizeof(value); 163 value.dataType = type; 164 value.data = data; 165 return util::make_unique<BinaryPrimitive>(value); 166 } 167 168 AttributeBuilder::AttributeBuilder() 169 : attr_(util::make_unique<Attribute>(android::ResTable_map::TYPE_ANY)) { 170 } 171 172 AttributeBuilder& AttributeBuilder::SetTypeMask(uint32_t typeMask) { 173 attr_->type_mask = typeMask; 174 return *this; 175 } 176 177 AttributeBuilder& AttributeBuilder::SetWeak(bool weak) { 178 attr_->SetWeak(weak); 179 return *this; 180 } 181 182 AttributeBuilder& AttributeBuilder::AddItem(const StringPiece& name, uint32_t value) { 183 attr_->symbols.push_back( 184 Attribute::Symbol{Reference(ResourceName({}, ResourceType::kId, name)), value}); 185 return *this; 186 } 187 188 std::unique_ptr<Attribute> AttributeBuilder::Build() { 189 return std::move(attr_); 190 } 191 192 StyleBuilder& StyleBuilder::SetParent(const StringPiece& str) { 193 style_->parent = Reference(ParseNameOrDie(str)); 194 return *this; 195 } 196 197 StyleBuilder& StyleBuilder::AddItem(const StringPiece& str, std::unique_ptr<Item> value) { 198 style_->entries.push_back(Style::Entry{Reference(ParseNameOrDie(str)), std::move(value)}); 199 return *this; 200 } 201 202 StyleBuilder& StyleBuilder::AddItem(const StringPiece& str, const ResourceId& id, 203 std::unique_ptr<Item> value) { 204 AddItem(str, std::move(value)); 205 style_->entries.back().key.id = id; 206 return *this; 207 } 208 209 std::unique_ptr<Style> StyleBuilder::Build() { 210 return std::move(style_); 211 } 212 213 StyleableBuilder& StyleableBuilder::AddItem(const StringPiece& str, const Maybe<ResourceId>& id) { 214 styleable_->entries.push_back(Reference(ParseNameOrDie(str))); 215 styleable_->entries.back().id = id; 216 return *this; 217 } 218 219 std::unique_ptr<Styleable> StyleableBuilder::Build() { 220 return std::move(styleable_); 221 } 222 223 std::unique_ptr<xml::XmlResource> BuildXmlDom(const StringPiece& str) { 224 std::string input = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; 225 input.append(str.data(), str.size()); 226 StringInputStream in(input); 227 StdErrDiagnostics diag; 228 std::unique_ptr<xml::XmlResource> doc = xml::Inflate(&in, &diag, Source("test.xml")); 229 CHECK(doc != nullptr && doc->root != nullptr) << "failed to parse inline XML string"; 230 return doc; 231 } 232 233 std::unique_ptr<xml::XmlResource> BuildXmlDomForPackageName(IAaptContext* context, 234 const StringPiece& str) { 235 std::unique_ptr<xml::XmlResource> doc = BuildXmlDom(str); 236 doc->file.name.package = context->GetCompilationPackage(); 237 return doc; 238 } 239 240 ArtifactBuilder& ArtifactBuilder::SetName(const std::string& name) { 241 artifact_.name = name; 242 return *this; 243 } 244 245 ArtifactBuilder& ArtifactBuilder::SetVersion(int version) { 246 artifact_.version = version; 247 return *this; 248 } 249 250 ArtifactBuilder& ArtifactBuilder::AddAbi(configuration::Abi abi) { 251 artifact_.abis.push_back(abi); 252 return *this; 253 } 254 255 ArtifactBuilder& ArtifactBuilder::AddDensity(const ConfigDescription& density) { 256 artifact_.screen_densities.push_back(density); 257 return *this; 258 } 259 260 ArtifactBuilder& ArtifactBuilder::AddLocale(const ConfigDescription& locale) { 261 artifact_.locales.push_back(locale); 262 return *this; 263 } 264 265 ArtifactBuilder& ArtifactBuilder::SetAndroidSdk(int min_sdk) { 266 artifact_.android_sdk = {AndroidSdk::ForMinSdk(min_sdk)}; 267 return *this; 268 } 269 270 configuration::OutputArtifact ArtifactBuilder::Build() { 271 return artifact_; 272 } 273 274 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddAbiGroup( 275 const std::string& label, std::vector<configuration::Abi> abis) { 276 return AddGroup(label, &config_.abi_groups, std::move(abis)); 277 } 278 279 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddDensityGroup( 280 const std::string& label, std::vector<std::string> densities) { 281 std::vector<ConfigDescription> configs; 282 for (const auto& density : densities) { 283 configs.push_back(test::ParseConfigOrDie(density)); 284 } 285 return AddGroup(label, &config_.screen_density_groups, configs); 286 } 287 288 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddLocaleGroup( 289 const std::string& label, std::vector<std::string> locales) { 290 std::vector<ConfigDescription> configs; 291 for (const auto& locale : locales) { 292 configs.push_back(test::ParseConfigOrDie(locale)); 293 } 294 return AddGroup(label, &config_.locale_groups, configs); 295 } 296 297 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddDeviceFeatureGroup( 298 const std::string& label) { 299 return AddGroup(label, &config_.device_feature_groups); 300 } 301 302 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddGlTextureGroup( 303 const std::string& label) { 304 return AddGroup(label, &config_.gl_texture_groups); 305 } 306 307 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddAndroidSdk( 308 std::string label, int min_sdk) { 309 config_.android_sdks[label] = AndroidSdk::ForMinSdk(min_sdk); 310 return *this; 311 } 312 313 PostProcessingConfigurationBuilder& PostProcessingConfigurationBuilder::AddArtifact( 314 configuration::ConfiguredArtifact artifact) { 315 config_.artifacts.push_back(std::move(artifact)); 316 return *this; 317 } 318 319 configuration::PostProcessingConfiguration PostProcessingConfigurationBuilder::Build() { 320 return config_; 321 } 322 323 } // namespace test 324 } // namespace aapt 325