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