blob: 1b815c1197cad334ae003b1d2a08c5061a5daeeb [file] [log] [blame]
Mårten Kongstad02751232018-04-27 13:16:32 +02001/*
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 *
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -070020 * idmap := header data*
21 * header := magic version target_crc overlay_crc fulfilled_policies
Ryan Mitchell30dc2e02020-12-02 11:43:18 -080022 * enforce_overlayable target_path overlay_path overlay_name
23 * debug_info
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -070024 * data := data_header target_entry* target_inline_entry* overlay_entry*
25 * string_pool
26 * data_header := target_package_id overlay_package_id padding(2) target_entry_count
27 * target_inline_entry_count overlay_entry_count string_pool_index
28 * target_entry := target_id overlay_id
29 * target_inline_entry := target_id Res_value::size padding(1) Res_value::type
30 * Res_value::value
31 * overlay_entry := overlay_id target_id
Mårten Kongstad02751232018-04-27 13:16:32 +020032 *
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -070033 * debug_info := string
34 * enforce_overlayable := <uint32_t>
35 * fulfilled_policies := <uint32_t>
36 * magic := <uint32_t>
37 * overlay_crc := <uint32_t>
38 * overlay_entry_count := <uint32_t>
39 * overlay_id := <uint32_t>
40 * overlay_package_id := <uint8_t>
Ryan Mitchell30dc2e02020-12-02 11:43:18 -080041 * overlay_name := string
Ryan Mitchell0699f1d2020-12-03 15:41:42 -080042 * overlay_path := string
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -070043 * padding(n) := <uint8_t>[n]
44 * Res_value::size := <uint16_t>
45 * Res_value::type := <uint8_t>
46 * Res_value::value := <uint32_t>
47 * string := <uint32_t> <uint8_t>+ padding(n)
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -070048 * string_pool := string
49 * string_pool_index := <uint32_t>
50 * string_pool_length := <uint32_t>
51 * target_crc := <uint32_t>
52 * target_entry_count := <uint32_t>
53 * target_inline_entry_count := <uint32_t>
54 * target_id := <uint32_t>
55 * target_package_id := <uint8_t>
Ryan Mitchell0699f1d2020-12-03 15:41:42 -080056 * target_path := string
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -070057 * value_type := <uint8_t>
58 * value_data := <uint32_t>
59 * version := <uint32_t>
Mårten Kongstad02751232018-04-27 13:16:32 +020060 */
61
62#ifndef IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
63#define IDMAP2_INCLUDE_IDMAP2_IDMAP_H_
64
65#include <iostream>
66#include <memory>
67#include <string>
68#include <vector>
69
70#include "android-base/macros.h"
Mårten Kongstad02751232018-04-27 13:16:32 +020071#include "androidfw/ApkAssets.h"
72#include "androidfw/ResourceTypes.h"
73#include "androidfw/StringPiece.h"
Ryan Mitchell9e4f52b2019-09-19 12:15:52 -070074#include "idmap2/ResourceMapping.h"
Ryan Mitchell7d53f192020-04-24 17:45:25 -070075#include "idmap2/ZipFile.h"
Mårten Kongstadd10d06d2019-01-07 17:26:25 -080076
Mårten Kongstad0eba72a2018-11-29 08:23:14 +010077namespace android::idmap2 {
Mårten Kongstad02751232018-04-27 13:16:32 +020078
79class Idmap;
80class Visitor;
81
Mårten Kongstad02751232018-04-27 13:16:32 +020082// magic number: all idmap files start with this
83static constexpr const uint32_t kIdmapMagic = android::kIdmapMagic;
84
85// current version of the idmap binary format; must be incremented when the format is changed
86static constexpr const uint32_t kIdmapCurrentVersion = android::kIdmapCurrentVersion;
87
Ryan Mitchell7d53f192020-04-24 17:45:25 -070088// Retrieves a crc generated using all of the files within the zip that can affect idmap generation.
89Result<uint32_t> GetPackageCrc(const ZipFile& zip_info);
90
Mårten Kongstad02751232018-04-27 13:16:32 +020091class IdmapHeader {
92 public:
93 static std::unique_ptr<const IdmapHeader> FromBinaryStream(std::istream& stream);
94
95 inline uint32_t GetMagic() const {
96 return magic_;
97 }
98
99 inline uint32_t GetVersion() const {
100 return version_;
101 }
102
103 inline uint32_t GetTargetCrc() const {
104 return target_crc_;
105 }
106
107 inline uint32_t GetOverlayCrc() const {
108 return overlay_crc_;
109 }
110
Ryan Mitchella7070132020-05-13 14:17:52 -0700111 inline uint32_t GetFulfilledPolicies() const {
112 return fulfilled_policies_;
113 }
114
115 bool GetEnforceOverlayable() const {
116 return enforce_overlayable_;
117 }
118
Ryan Mitchell0699f1d2020-12-03 15:41:42 -0800119 const std::string& GetTargetPath() const {
120 return target_path_;
Mårten Kongstad02751232018-04-27 13:16:32 +0200121 }
122
Ryan Mitchell0699f1d2020-12-03 15:41:42 -0800123 const std::string& GetOverlayPath() const {
124 return overlay_path_;
Mårten Kongstad02751232018-04-27 13:16:32 +0200125 }
126
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800127 const std::string& GetOverlayName() const {
128 return overlay_name_;
129 }
130
Ryan Mitchell0699f1d2020-12-03 15:41:42 -0800131 const std::string& GetDebugInfo() const {
Mårten Kongstadd7e8a532019-10-11 08:32:04 +0200132 return debug_info_;
133 }
134
Mårten Kongstad02751232018-04-27 13:16:32 +0200135 // Invariant: anytime the idmap data encoding is changed, the idmap version
136 // field *must* be incremented. Because of this, we know that if the idmap
137 // header is up-to-date the entire file is up-to-date.
Ryan Mitchell0699f1d2020-12-03 15:41:42 -0800138 Result<Unit> IsUpToDate(const std::string& target_path, const std::string& overlay_path,
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800139 const std::string& overlay_name, PolicyBitmask fulfilled_policies,
140 bool enforce_overlayable) const;
141
Ryan Mitchell0699f1d2020-12-03 15:41:42 -0800142 Result<Unit> IsUpToDate(const std::string& target_path, const std::string& overlay_path,
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800143 const std::string& overlay_name, uint32_t target_crc,
144 uint32_t overlay_crc, PolicyBitmask fulfilled_policies,
145 bool enforce_overlayable) const;
Mårten Kongstad02751232018-04-27 13:16:32 +0200146
147 void accept(Visitor* v) const;
148
149 private:
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800150 IdmapHeader() = default;
Mårten Kongstad02751232018-04-27 13:16:32 +0200151
152 uint32_t magic_;
153 uint32_t version_;
154 uint32_t target_crc_;
155 uint32_t overlay_crc_;
Ryan Mitchella7070132020-05-13 14:17:52 -0700156 uint32_t fulfilled_policies_;
157 bool enforce_overlayable_;
Ryan Mitchell0699f1d2020-12-03 15:41:42 -0800158 std::string target_path_;
159 std::string overlay_path_;
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800160 std::string overlay_name_;
Mårten Kongstadd7e8a532019-10-11 08:32:04 +0200161 std::string debug_info_;
Mårten Kongstad02751232018-04-27 13:16:32 +0200162
163 friend Idmap;
164 DISALLOW_COPY_AND_ASSIGN(IdmapHeader);
165};
Mårten Kongstad02751232018-04-27 13:16:32 +0200166class IdmapData {
167 public:
168 class Header {
169 public:
170 static std::unique_ptr<const Header> FromBinaryStream(std::istream& stream);
171
172 inline PackageId GetTargetPackageId() const {
173 return target_package_id_;
174 }
175
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700176 inline PackageId GetOverlayPackageId() const {
177 return overlay_package_id_;
178 }
179
180 inline uint32_t GetTargetEntryCount() const {
181 return target_entry_count;
182 }
183
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700184 inline uint32_t GetTargetInlineEntryCount() const {
185 return target_entry_inline_count;
186 }
187
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700188 inline uint32_t GetOverlayEntryCount() const {
189 return overlay_entry_count;
190 }
191
192 inline uint32_t GetStringPoolIndexOffset() const {
193 return string_pool_index_offset;
194 }
195
Mårten Kongstad02751232018-04-27 13:16:32 +0200196 void accept(Visitor* v) const;
197
198 private:
Mårten Kongstad02751232018-04-27 13:16:32 +0200199 PackageId target_package_id_;
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700200 PackageId overlay_package_id_;
201 uint32_t target_entry_count;
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700202 uint32_t target_entry_inline_count;
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700203 uint32_t overlay_entry_count;
204 uint32_t string_pool_index_offset;
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700205 Header() = default;
Mårten Kongstad02751232018-04-27 13:16:32 +0200206
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700207 friend Idmap;
Ryan Mitchell9e4f52b2019-09-19 12:15:52 -0700208 friend IdmapData;
Mårten Kongstad02751232018-04-27 13:16:32 +0200209 DISALLOW_COPY_AND_ASSIGN(Header);
210 };
211
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700212 struct TargetEntry {
213 ResourceId target_id;
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700214 ResourceId overlay_id;
215 };
216
217 struct TargetInlineEntry {
218 ResourceId target_id;
219 TargetValue value;
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700220 };
Mårten Kongstad02751232018-04-27 13:16:32 +0200221
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700222 struct OverlayEntry {
223 ResourceId overlay_id;
224 ResourceId target_id;
Mårten Kongstad02751232018-04-27 13:16:32 +0200225 };
226
227 static std::unique_ptr<const IdmapData> FromBinaryStream(std::istream& stream);
228
Ryan Mitchell9e4f52b2019-09-19 12:15:52 -0700229 static Result<std::unique_ptr<const IdmapData>> FromResourceMapping(
230 const ResourceMapping& resource_mapping);
231
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700232 const std::unique_ptr<const Header>& GetHeader() const {
Mårten Kongstad02751232018-04-27 13:16:32 +0200233 return header_;
234 }
235
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700236 const std::vector<TargetEntry>& GetTargetEntries() const {
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700237 return target_entries_;
238 }
239
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700240 const std::vector<TargetInlineEntry>& GetTargetInlineEntries() const {
241 return target_inline_entries_;
242 }
243
244 const std::vector<OverlayEntry>& GetOverlayEntries() const {
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700245 return overlay_entries_;
246 }
247
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700248 const std::string& GetStringPoolData() const {
249 return string_pool_data_;
Mårten Kongstad02751232018-04-27 13:16:32 +0200250 }
251
252 void accept(Visitor* v) const;
253
254 private:
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800255 IdmapData() = default;
Mårten Kongstad02751232018-04-27 13:16:32 +0200256
257 std::unique_ptr<const Header> header_;
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700258 std::vector<TargetEntry> target_entries_;
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700259 std::vector<TargetInlineEntry> target_inline_entries_;
Ryan Mitchelle753ffe2019-09-23 09:47:02 -0700260 std::vector<OverlayEntry> overlay_entries_;
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700261 std::string string_pool_data_;
Mårten Kongstad02751232018-04-27 13:16:32 +0200262
263 friend Idmap;
264 DISALLOW_COPY_AND_ASSIGN(IdmapData);
265};
266
267class Idmap {
268 public:
269 static std::string CanonicalIdmapPathFor(const std::string& absolute_dir,
270 const std::string& absolute_apk_path);
271
Mårten Kongstadce424902019-03-01 08:35:37 +0100272 static Result<std::unique_ptr<const Idmap>> FromBinaryStream(std::istream& stream);
Mårten Kongstad02751232018-04-27 13:16:32 +0200273
274 // In the current version of idmap, the first package in each resources.arsc
275 // file is used; change this in the next version of idmap to use a named
276 // package instead; also update FromApkAssets to take additional parameters:
277 // the target and overlay package names
Ryan Mitchell9e4f52b2019-09-19 12:15:52 -0700278 static Result<std::unique_ptr<const Idmap>> FromApkAssets(const ApkAssets& target_apk_assets,
Mårten Kongstadce424902019-03-01 08:35:37 +0100279 const ApkAssets& overlay_apk_assets,
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800280 const std::string& overlay_name,
Mårten Kongstadce424902019-03-01 08:35:37 +0100281 const PolicyBitmask& fulfilled_policies,
282 bool enforce_overlayable);
Mårten Kongstad02751232018-04-27 13:16:32 +0200283
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800284 const std::unique_ptr<const IdmapHeader>& GetHeader() const {
Mårten Kongstad02751232018-04-27 13:16:32 +0200285 return header_;
286 }
287
Ryan Mitchell30dc2e02020-12-02 11:43:18 -0800288 const std::vector<std::unique_ptr<const IdmapData>>& GetData() const {
Mårten Kongstad02751232018-04-27 13:16:32 +0200289 return data_;
290 }
291
292 void accept(Visitor* v) const;
293
294 private:
Ryan Mitchell0699f1d2020-12-03 15:41:42 -0800295 Idmap() = default;
Mårten Kongstad02751232018-04-27 13:16:32 +0200296
297 std::unique_ptr<const IdmapHeader> header_;
298 std::vector<std::unique_ptr<const IdmapData>> data_;
299
300 DISALLOW_COPY_AND_ASSIGN(Idmap);
301};
302
303class Visitor {
304 public:
Ryan Mitchell0699f1d2020-12-03 15:41:42 -0800305 virtual ~Visitor() = default;
Mårten Kongstad02751232018-04-27 13:16:32 +0200306 virtual void visit(const Idmap& idmap) = 0;
307 virtual void visit(const IdmapHeader& header) = 0;
308 virtual void visit(const IdmapData& data) = 0;
309 virtual void visit(const IdmapData::Header& header) = 0;
Mårten Kongstad02751232018-04-27 13:16:32 +0200310};
311
Ryan Mitchellbf1f45b2020-09-29 17:22:52 -0700312inline size_t CalculatePadding(size_t data_length) {
313 return (4 - (data_length % 4)) % 4;
314}
315
Mårten Kongstad0eba72a2018-11-29 08:23:14 +0100316} // namespace android::idmap2
Mårten Kongstad02751232018-04-27 13:16:32 +0200317
318#endif // IDMAP2_INCLUDE_IDMAP2_IDMAP_H_