blob: 22096ed82f4e3d604f4b6d9deea313dce80eaf63 [file] [log] [blame]
Adam Lesinski1ab598f2015-08-14 14:26:04 -07001/*
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_PROCESS_SYMBOLTABLE_H
18#define AAPT_PROCESS_SYMBOLTABLE_H
19
20#include "Resource.h"
21#include "ResourceTable.h"
22#include "ResourceValues.h"
23#include "util/Util.h"
24
25#include <utils/JenkinsHash.h>
26#include <utils/LruCache.h>
27
28#include <androidfw/AssetManager.h>
29#include <algorithm>
30#include <map>
31#include <memory>
32#include <vector>
33
34namespace aapt {
35
36struct ISymbolTable {
37 virtual ~ISymbolTable() = default;
38
39 struct Symbol {
40 ResourceId id;
41 std::unique_ptr<Attribute> attribute;
42 bool isPublic;
43 };
44
45 /**
46 * Never hold on to the result between calls to findByName or findById. The results
47 * are typically stored in a cache which may evict entries.
48 */
49 virtual const Symbol* findByName(const ResourceName& name) = 0;
50 virtual const Symbol* findById(ResourceId id) = 0;
51};
52
53inline android::hash_t hash_type(const ResourceName& name) {
54 std::hash<std::u16string> strHash;
55 android::hash_t hash = 0;
56 hash = android::JenkinsHashMix(hash, strHash(name.package));
57 hash = android::JenkinsHashMix(hash, (uint32_t) name.type);
58 hash = android::JenkinsHashMix(hash, strHash(name.entry));
59 return hash;
60}
61
62inline android::hash_t hash_type(const ResourceId& id) {
63 return android::hash_type(id.id);
64}
65
66/**
67 * Presents a ResourceTable as an ISymbolTable, caching results.
68 * Instances of this class must outlive the encompassed ResourceTable.
69 * Since symbols are cached, the ResourceTable should not change during the
70 * lifetime of this SymbolTableWrapper.
71 *
72 * If a resource in the ResourceTable does not have a ResourceID assigned to it,
73 * it is ignored.
74 *
75 * Lookups by ID are ignored.
76 */
77class SymbolTableWrapper : public ISymbolTable {
78private:
79 ResourceTable* mTable;
80
81 // We use shared_ptr because unique_ptr is not supported and
82 // we need automatic deletion.
83 android::LruCache<ResourceName, std::shared_ptr<Symbol>> mCache;
84
85public:
86 SymbolTableWrapper(ResourceTable* table) : mTable(table), mCache(200) {
87 }
88
89 const Symbol* findByName(const ResourceName& name) override;
90
91 // Unsupported, all queries to ResourceTable should be done by name.
92 const Symbol* findById(ResourceId id) override {
93 return {};
94 }
95};
96
97class AssetManagerSymbolTableBuilder {
98private:
99 struct AssetManagerSymbolTable : public ISymbolTable {
100 std::vector<std::unique_ptr<android::AssetManager>> mAssets;
101
102 // We use shared_ptr because unique_ptr is not supported and
103 // we need automatic deletion.
104 android::LruCache<ResourceName, std::shared_ptr<Symbol>> mCache;
105 android::LruCache<ResourceId, std::shared_ptr<Symbol>> mIdCache;
106
107 AssetManagerSymbolTable() : mCache(200), mIdCache(200) {
108 }
109
110 const Symbol* findByName(const ResourceName& name) override;
111 const Symbol* findById(ResourceId id) override;
112 };
113
114 std::unique_ptr<AssetManagerSymbolTable> mSymbolTable =
115 util::make_unique<AssetManagerSymbolTable>();
116
117public:
118 AssetManagerSymbolTableBuilder& add(std::unique_ptr<android::AssetManager> assetManager) {
119 mSymbolTable->mAssets.push_back(std::move(assetManager));
120 return *this;
121 }
122
123 std::unique_ptr<ISymbolTable> build() {
124 return std::move(mSymbolTable);
125 }
126};
127
128class JoinedSymbolTableBuilder {
129private:
130 struct JoinedSymbolTable : public ISymbolTable {
131 std::vector<std::unique_ptr<ISymbolTable>> mSymbolTables;
132
133 const Symbol* findByName(const ResourceName& name) override;
134 const Symbol* findById(ResourceId id) override;
135 };
136
137 std::unique_ptr<JoinedSymbolTable> mSymbolTable = util::make_unique<JoinedSymbolTable>();
138
139public:
140 JoinedSymbolTableBuilder& addSymbolTable(std::unique_ptr<ISymbolTable> table) {
141 mSymbolTable->mSymbolTables.push_back(std::move(table));
142 return *this;
143 }
144
145 std::unique_ptr<ISymbolTable> build() {
146 return std::move(mSymbolTable);
147 }
148};
149
150} // namespace aapt
151
152#endif /* AAPT_PROCESS_SYMBOLTABLE_H */