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