• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 /*
18  * # idmap file format (current version)
19  *
20  * idmap                      := header data*
21  * header                     := magic version target_crc overlay_crc fulfilled_policies
22  *                               enforce_overlayable target_path overlay_path overlay_name
23  *                               debug_info
24  * data                       := data_header target_entry* target_inline_entry*
25                                  target_inline_entry_value* config* overlay_entry* string_pool
26  * data_header                := target_entry_count target_inline_entry_count
27                                  target_inline_entry_value_count config_count overlay_entry_count
28  *                               string_pool_index
29  * target_entry               := target_id overlay_id
30  * target_inline_entry        := target_id start_value_index value_count
31  * target_inline_entry_value  := config_index Res_value::size padding(1) Res_value::type
32  *                               Res_value::value
33  * config                     := target_id Res_value::size padding(1) Res_value::type
34  *                               Res_value::value
35  * overlay_entry              := overlay_id target_id
36  *
37  * debug_info                       := string
38  * enforce_overlayable              := <uint32_t>
39  * fulfilled_policies               := <uint32_t>
40  * magic                            := <uint32_t>
41  * overlay_crc                      := <uint32_t>
42  * overlay_entry_count              := <uint32_t>
43  * overlay_id                       := <uint32_t>
44  * overlay_package_id               := <uint8_t>
45  * overlay_name                     := string
46  * overlay_path                     := string
47  * padding(n)                       := <uint8_t>[n]
48  * Res_value::size                  := <uint16_t>
49  * Res_value::type                  := <uint8_t>
50  * Res_value::value                 := <uint32_t>
51  * string                           := <uint32_t> <uint8_t>+ padding(n)
52  * string_pool                      := string
53  * string_pool_index                := <uint32_t>
54  * string_pool_length               := <uint32_t>
55  * target_crc                       := <uint32_t>
56  * target_entry_count               := <uint32_t>
57  * target_inline_entry_count        := <uint32_t>
58  * target_inline_entry_value_count  := <uint32_t>
59  * config_count                     := <uint32_t>
60  * config_index                     := <uint32_t>
61  * start_value_index                := <uint32_t>
62  * value_count                      := <uint32_t>
63  * target_id                        := <uint32_t>
64  * target_package_id                := <uint8_t>
65  * target_path                      := string
66  * value_type                       := <uint8_t>
67  * value_data                       := <uint32_t>
68  * version                          := <uint32_t>
69  */
70 
71 #ifndef IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
72 #define IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
73 
74 #include <istream>
75 #include <memory>
76 #include <string>
77 #include <string_view>
78 #include <vector>
79 
80 #include "android-base/macros.h"
81 #include "androidfw/ResourceTypes.h"
82 #include "androidfw/StringPiece.h"
83 #include "androidfw/ConfigDescription.h"
84 #include "idmap2/ResourceContainer.h"
85 #include "idmap2/ResourceMapping.h"
86 
87 namespace android::idmap2 {
88 
89 class Idmap;
90 class Visitor;
91 
92 // magic number: all idmap files start with this
93 static constexpr const uint32_t kIdmapMagic = android::kIdmapMagic;
94 
95 // current version of the idmap binary format; must be incremented when the format is changed
96 static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVersion;
97 
98 class IdmapHeader {
99  public:
100   static std::unique_ptr<const IdmapHeader> FromBinaryStream(std::istream& stream);
101 
GetMagic()102   inline uint32_t GetMagic() const {
103     return magic_;
104   }
105 
GetVersion()106   inline uint32_t GetVersion() const {
107     return version_;
108   }
109 
GetTargetCrc()110   inline uint32_t GetTargetCrc() const {
111     return target_crc_;
112   }
113 
GetOverlayCrc()114   inline uint32_t GetOverlayCrc() const {
115     return overlay_crc_;
116   }
117 
GetFulfilledPolicies()118   inline uint32_t GetFulfilledPolicies() const {
119     return fulfilled_policies_;
120   }
121 
GetEnforceOverlayable()122   bool GetEnforceOverlayable() const {
123     return enforce_overlayable_;
124   }
125 
GetTargetPath()126   const std::string& GetTargetPath() const {
127     return target_path_;
128   }
129 
GetOverlayPath()130   const std::string& GetOverlayPath() const {
131     return overlay_path_;
132   }
133 
GetOverlayName()134   const std::string& GetOverlayName() const {
135     return overlay_name_;
136   }
137 
GetDebugInfo()138   const std::string& GetDebugInfo() const {
139     return debug_info_;
140   }
141 
142   // Invariant: anytime the idmap data encoding is changed, the idmap version
143   // field *must* be incremented. Because of this, we know that if the idmap
144   // header is up-to-date the entire file is up-to-date.
145   Result<Unit> IsUpToDate(const TargetResourceContainer& target,
146                           const OverlayResourceContainer& overlay, const std::string& overlay_name,
147                           PolicyBitmask fulfilled_policies, bool enforce_overlayable) const;
148 
149   Result<Unit> IsUpToDate(const std::string& target_path, const std::string& overlay_path,
150                           const std::string& overlay_name, uint32_t target_crc,
151                           uint32_t overlay_crc, PolicyBitmask fulfilled_policies,
152                           bool enforce_overlayable) const;
153 
154   void accept(Visitor* v) const;
155 
156  private:
157   IdmapHeader() = default;
158 
159   uint32_t magic_;
160   uint32_t version_;
161   uint32_t target_crc_;
162   uint32_t overlay_crc_;
163   uint32_t fulfilled_policies_;
164   bool enforce_overlayable_;
165   std::string target_path_;
166   std::string overlay_path_;
167   std::string overlay_name_;
168   std::string debug_info_;
169 
170   friend Idmap;
171   DISALLOW_COPY_AND_ASSIGN(IdmapHeader);
172 };
173 class IdmapData {
174  public:
175   class Header {
176    public:
177     static std::unique_ptr<const Header> FromBinaryStream(std::istream& stream);
178 
GetTargetEntryCount()179     [[nodiscard]] inline uint32_t GetTargetEntryCount() const {
180       return target_entry_count;
181     }
182 
GetTargetInlineEntryCount()183     [[nodiscard]] inline uint32_t GetTargetInlineEntryCount() const {
184       return target_entry_inline_count;
185     }
186 
GetTargetInlineEntryValueCount()187     [[nodiscard]] inline uint32_t GetTargetInlineEntryValueCount() const {
188       return target_entry_inline_value_count;
189     }
190 
GetConfigCount()191     [[nodiscard]] inline uint32_t GetConfigCount() const {
192       return config_count;
193     }
194 
GetOverlayEntryCount()195     [[nodiscard]] inline uint32_t GetOverlayEntryCount() const {
196       return overlay_entry_count;
197     }
198 
GetStringPoolIndexOffset()199     [[nodiscard]] inline uint32_t GetStringPoolIndexOffset() const {
200       return string_pool_index_offset;
201     }
202 
203     void accept(Visitor* v) const;
204 
205    private:
206     uint32_t target_entry_count;
207     uint32_t target_entry_inline_count;
208     uint32_t target_entry_inline_value_count;
209     uint32_t config_count;
210     uint32_t overlay_entry_count;
211     uint32_t string_pool_index_offset;
212     Header() = default;
213 
214     friend Idmap;
215     friend IdmapData;
216     DISALLOW_COPY_AND_ASSIGN(Header);
217   };
218 
219   struct TargetEntry {
220     ResourceId target_id;
221     ResourceId overlay_id;
222   };
223 
224   struct TargetInlineEntry {
225     ResourceId target_id;
226     std::map<ConfigDescription, TargetValue> values;
227   };
228 
229   struct OverlayEntry {
230     ResourceId overlay_id;
231     ResourceId target_id;
232   };
233 
234   static std::unique_ptr<const IdmapData> FromBinaryStream(std::istream& stream);
235 
236   static Result<std::unique_ptr<const IdmapData>> FromResourceMapping(
237       const ResourceMapping& resource_mapping);
238 
GetHeader()239   const std::unique_ptr<const Header>& GetHeader() const {
240     return header_;
241   }
242 
GetTargetEntries()243   const std::vector<TargetEntry>& GetTargetEntries() const {
244     return target_entries_;
245   }
246 
GetTargetInlineEntries()247   const std::vector<TargetInlineEntry>& GetTargetInlineEntries() const {
248     return target_inline_entries_;
249   }
250 
GetOverlayEntries()251   [[nodiscard]] const std::vector<OverlayEntry>& GetOverlayEntries() const {
252     return overlay_entries_;
253   }
254 
GetStringPoolData()255   [[nodiscard]] const std::string& GetStringPoolData() const {
256     return string_pool_data_;
257   }
258 
259   void accept(Visitor* v) const;
260 
261  private:
262   IdmapData() = default;
263 
264   std::unique_ptr<const Header> header_;
265   std::vector<TargetEntry> target_entries_;
266   std::vector<TargetInlineEntry> target_inline_entries_;
267   std::vector<OverlayEntry> overlay_entries_;
268   std::string string_pool_data_;
269 
270   friend Idmap;
271   DISALLOW_COPY_AND_ASSIGN(IdmapData);
272 };
273 
274 class Idmap {
275  public:
276   static std::string CanonicalIdmapPathFor(std::string_view absolute_dir,
277                                            std::string_view absolute_apk_path);
278 
279   static Result<std::unique_ptr<const Idmap>> FromBinaryStream(std::istream& stream);
280 
281   // In the current version of idmap, the first package in each resources.arsc
282   // file is used; change this in the next version of idmap to use a named
283   // package instead; also update FromApkAssets to take additional parameters:
284   // the target and overlay package names
285   static Result<std::unique_ptr<const Idmap>> FromContainers(
286       const TargetResourceContainer& target, const OverlayResourceContainer& overlay,
287       const std::string& overlay_name, const PolicyBitmask& fulfilled_policies,
288       bool enforce_overlayable);
289 
GetHeader()290   const std::unique_ptr<const IdmapHeader>& GetHeader() const {
291     return header_;
292   }
293 
GetData()294   const std::vector<std::unique_ptr<const IdmapData>>& GetData() const {
295     return data_;
296   }
297 
298   void accept(Visitor* v) const;
299 
300  private:
301   Idmap() = default;
302 
303   std::unique_ptr<const IdmapHeader> header_;
304   std::vector<std::unique_ptr<const IdmapData>> data_;
305 
306   DISALLOW_COPY_AND_ASSIGN(Idmap);
307 };
308 
309 class Visitor {
310  public:
311   virtual ~Visitor() = default;
312   virtual void visit(const Idmap& idmap) = 0;
313   virtual void visit(const IdmapHeader& header) = 0;
314   virtual void visit(const IdmapData& data) = 0;
315   virtual void visit(const IdmapData::Header& header) = 0;
316 };
317 
CalculatePadding(size_t data_length)318 inline size_t CalculatePadding(size_t data_length) {
319   return (4 - (data_length % 4)) % 4;
320 }
321 
322 }  // namespace android::idmap2
323 
324 #endif  // IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
325