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