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_CONTEXT_H 18 #define AAPT_TEST_CONTEXT_H 19 20 #include <list> 21 22 #include "android-base/logging.h" 23 #include "android-base/macros.h" 24 25 #include "NameMangler.h" 26 #include "process/IResourceTableConsumer.h" 27 #include "process/SymbolTable.h" 28 #include "test/Common.h" 29 #include "util/Util.h" 30 31 namespace aapt { 32 namespace test { 33 34 class Context : public IAaptContext { 35 public: 36 Context() : name_mangler_({}), symbols_(&name_mangler_), min_sdk_version_(0) {} 37 38 PackageType GetPackageType() override { 39 return package_type_; 40 } 41 42 SymbolTable* GetExternalSymbols() override { 43 return &symbols_; 44 } 45 46 IDiagnostics* GetDiagnostics() override { 47 return &diagnostics_; 48 } 49 50 const std::string& GetCompilationPackage() override { 51 CHECK(bool(compilation_package_)) << "package name not set"; 52 return compilation_package_.value(); 53 } 54 55 void SetCompilationPackage(const android::StringPiece& package) { 56 compilation_package_ = package.to_string(); 57 } 58 59 uint8_t GetPackageId() override { 60 CHECK(bool(package_id_)) << "package ID not set"; 61 return package_id_.value(); 62 } 63 64 void SetPackageId(uint8_t package_id) { 65 package_id_ = package_id; 66 } 67 68 NameMangler* GetNameMangler() override { 69 return &name_mangler_; 70 } 71 72 void SetNameManglerPolicy(const NameManglerPolicy& policy) { 73 name_mangler_ = NameMangler(policy); 74 } 75 76 bool IsVerbose() override { 77 return false; 78 } 79 80 int GetMinSdkVersion() override { 81 return min_sdk_version_; 82 } 83 84 private: 85 DISALLOW_COPY_AND_ASSIGN(Context); 86 87 friend class ContextBuilder; 88 89 PackageType package_type_ = PackageType::kApp; 90 Maybe<std::string> compilation_package_; 91 Maybe<uint8_t> package_id_; 92 StdErrDiagnostics diagnostics_; 93 NameMangler name_mangler_; 94 SymbolTable symbols_; 95 int min_sdk_version_; 96 }; 97 98 class ContextBuilder { 99 public: 100 ContextBuilder& SetPackageType(PackageType type) { 101 context_->package_type_ = type; 102 return *this; 103 } 104 105 ContextBuilder& SetCompilationPackage(const android::StringPiece& package) { 106 context_->compilation_package_ = package.to_string(); 107 return *this; 108 } 109 110 ContextBuilder& SetPackageId(uint8_t id) { 111 context_->package_id_ = id; 112 return *this; 113 } 114 115 ContextBuilder& SetNameManglerPolicy(const NameManglerPolicy& policy) { 116 context_->name_mangler_ = NameMangler(policy); 117 return *this; 118 } 119 120 ContextBuilder& AddSymbolSource(std::unique_ptr<ISymbolSource> src) { 121 context_->GetExternalSymbols()->AppendSource(std::move(src)); 122 return *this; 123 } 124 125 ContextBuilder& SetMinSdkVersion(int min_sdk) { 126 context_->min_sdk_version_ = min_sdk; 127 return *this; 128 } 129 130 std::unique_ptr<Context> Build() { return std::move(context_); } 131 132 private: 133 std::unique_ptr<Context> context_ = std::unique_ptr<Context>(new Context()); 134 }; 135 136 class StaticSymbolSourceBuilder { 137 public: 138 StaticSymbolSourceBuilder& AddPublicSymbol(const android::StringPiece& name, ResourceId id, 139 std::unique_ptr<Attribute> attr = {}) { 140 std::unique_ptr<SymbolTable::Symbol> symbol = 141 util::make_unique<SymbolTable::Symbol>(id, std::move(attr), true); 142 symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get(); 143 symbol_source_->id_map_[id] = symbol.get(); 144 symbol_source_->symbols_.push_back(std::move(symbol)); 145 return *this; 146 } 147 148 StaticSymbolSourceBuilder& AddSymbol(const android::StringPiece& name, ResourceId id, 149 std::unique_ptr<Attribute> attr = {}) { 150 std::unique_ptr<SymbolTable::Symbol> symbol = 151 util::make_unique<SymbolTable::Symbol>(id, std::move(attr), false); 152 symbol_source_->name_map_[ParseNameOrDie(name)] = symbol.get(); 153 symbol_source_->id_map_[id] = symbol.get(); 154 symbol_source_->symbols_.push_back(std::move(symbol)); 155 return *this; 156 } 157 158 std::unique_ptr<ISymbolSource> Build() { 159 return std::move(symbol_source_); 160 } 161 162 private: 163 class StaticSymbolSource : public ISymbolSource { 164 public: 165 StaticSymbolSource() = default; 166 167 std::unique_ptr<SymbolTable::Symbol> FindByName(const ResourceName& name) override { 168 auto iter = name_map_.find(name); 169 if (iter != name_map_.end()) { 170 return CloneSymbol(iter->second); 171 } 172 return nullptr; 173 } 174 175 std::unique_ptr<SymbolTable::Symbol> FindById(ResourceId id) override { 176 auto iter = id_map_.find(id); 177 if (iter != id_map_.end()) { 178 return CloneSymbol(iter->second); 179 } 180 return nullptr; 181 } 182 183 std::list<std::unique_ptr<SymbolTable::Symbol>> symbols_; 184 std::map<ResourceName, SymbolTable::Symbol*> name_map_; 185 std::map<ResourceId, SymbolTable::Symbol*> id_map_; 186 187 private: 188 std::unique_ptr<SymbolTable::Symbol> CloneSymbol(SymbolTable::Symbol* sym) { 189 std::unique_ptr<SymbolTable::Symbol> clone = util::make_unique<SymbolTable::Symbol>(); 190 clone->id = sym->id; 191 if (sym->attribute) { 192 clone->attribute = std::unique_ptr<Attribute>(sym->attribute->Clone(nullptr)); 193 } 194 clone->is_public = sym->is_public; 195 return clone; 196 } 197 198 DISALLOW_COPY_AND_ASSIGN(StaticSymbolSource); 199 }; 200 201 std::unique_ptr<StaticSymbolSource> symbol_source_ = util::make_unique<StaticSymbolSource>(); 202 }; 203 204 } // namespace test 205 } // namespace aapt 206 207 #endif /* AAPT_TEST_CONTEXT_H */ 208