blob: c5331fb87381b3e4bae01f3b1d2c85d710ae98a4 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef AAPT_TEST_CONTEXT_H
#define AAPT_TEST_CONTEXT_H
#include <list>
#include "Diagnostics.h"
#include "NameMangler.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "process/IResourceTableConsumer.h"
#include "process/SymbolTable.h"
#include "test/Common.h"
#include "util/Util.h"
namespace aapt {
namespace test {
class Context : public IAaptContext {
public:
Context() : name_mangler_({}), symbols_(&name_mangler_), min_sdk_version_(0) {}
PackageType GetPackageType() override {
return package_type_;
}
SymbolTable* GetExternalSymbols() override {
return &symbols_;
}
android::IDiagnostics* GetDiagnostics() override {
return &diagnostics_;
}
const std::string& GetCompilationPackage() override {
CHECK(bool(compilation_package_)) << "package name not set";
return compilation_package_.value();
}
void SetCompilationPackage(android::StringPiece package) {
compilation_package_ = std::string(package);
}
uint8_t GetPackageId() override {
CHECK(bool(package_id_)) << "package ID not set";
return package_id_.value();
}
void SetPackageId(uint8_t package_id) {
package_id_ = package_id;
}
NameMangler* GetNameMangler() override {
return &name_mangler_;
}
void SetNameManglerPolicy(const NameManglerPolicy& policy) {
name_mangler_ = NameMangler(policy);
}
bool IsVerbose() override {
return false;
}
int GetMinSdkVersion() override {
return min_sdk_version_;
}
void SetMinSdkVersion(int min_sdk_version) {
min_sdk_version_ = min_sdk_version;
}
const std::set<std::string>& GetSplitNameDependencies() override {
return split_name_dependencies_;
}
private:
DISALLOW_COPY_AND_ASSIGN(Context);
friend class ContextBuilder;
PackageType package_type_ = PackageType::kApp;
std::optional<std::string> compilation_package_;
std::optional<uint8_t> package_id_;
StdErrDiagnostics diagnostics_;
NameMangler name_mangler_;
SymbolTable symbols_;
int min_sdk_version_;
std::set<std::string> split_name_dependencies_;
};
class ContextBuilder {
public:
ContextBuilder& SetPackageType(PackageType type) {
context_->package_type_ = type;
return *this;
}
ContextBuilder& SetCompilationPackage(android::StringPiece package) {
context_->compilation_package_ = std::string(package);
return *this;
}
ContextBuilder& SetPackageId(uint8_t id) {
context_->package_id_ = id;
return *this;
}
ContextBuilder& SetNameManglerPolicy(const NameManglerPolicy& policy) {
context_->name_mangler_ = NameMangler(policy);
return *this;
}
ContextBuilder& AddSymbolSource(std::unique_ptr<ISymbolSource> src) {
context_->GetExternalSymbols()->AppendSource(std::move(src));
return *this;
}
ContextBuilder& SetMinSdkVersion(int min_sdk) {
context_->min_sdk_version_ = min_sdk;
return *this;
}
ContextBuilder& SetSplitNameDependencies(const std::set<std::string>& split_name_dependencies) {
context_->split_name_dependencies_ = split_name_dependencies;
return *this;
}
std::unique_ptr<Context> Build() { return std::move(context_); }
private:
std::unique_ptr<Context> context_ = std::unique_ptr<Context>(new Context());
};
class StaticSymbolSourceBuilder {
public:
StaticSymbolSourceBuilder& AddPublicSymbol(android::StringPiece name, ResourceId id,
std::unique_ptr<Attribute> attr = {}) {
std::unique_ptr<SymbolTable::Symbol> symbol =
util::make_unique<SymbolTable::Symbol>(id, std::move(attr), true);
symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get();
symbol_source_->id_map_[id] = symbol.get();
symbol_source_->symbols_.push_back(std::move(symbol));
return *this;
}
StaticSymbolSourceBuilder& AddSymbol(android::StringPiece name, ResourceId id,
std::unique_ptr<Attribute> attr = {}) {
std::unique_ptr<SymbolTable::Symbol> symbol =
util::make_unique<SymbolTable::Symbol>(id, std::move(attr), false);
symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get();
symbol_source_->id_map_[id] = symbol.get();
symbol_source_->symbols_.push_back(std::move(symbol));
return *this;
}
std::unique_ptr<ISymbolSource> Build() {
return std::move(symbol_source_);
}
private:
class StaticSymbolSource : public ISymbolSource {
public:
StaticSymbolSource() = default;
std::unique_ptr<SymbolTable::Symbol> FindByName(const ResourceName& name) override {
auto iter = name_map_.find(name);
if (iter != name_map_.end()) {
return CloneSymbol(iter->second);
}
return nullptr;
}
std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override {
auto iter = id_map_.find(id);
if (iter != id_map_.end()) {
return CloneSymbol(iter->second);
}
return nullptr;
}
std::list<std::unique_ptr<SymbolTable::Symbol>> symbols_;
std::map<ResourceName, SymbolTable::Symbol*> name_map_;
std::map<ResourceId, SymbolTable::Symbol*> id_map_;
private:
std::unique_ptr<SymbolTable::Symbol> CloneSymbol(SymbolTable::Symbol* sym) {
CloningValueTransformer cloner(nullptr);
std::unique_ptr<SymbolTable::Symbol> clone = util::make_unique<SymbolTable::Symbol>();
clone->id = sym->id;
if (sym->attribute) {
clone->attribute = std::unique_ptr<Attribute>(sym->attribute->Transform(cloner));
}
clone->is_public = sym->is_public;
return clone;
}
DISALLOW_COPY_AND_ASSIGN(StaticSymbolSource);
};
std::unique_ptr<StaticSymbolSource> symbol_source_ = util::make_unique<StaticSymbolSource>();
};
} // namespace test
} // namespace aapt
#endif /* AAPT_TEST_CONTEXT_H */