1 /*
2 * Copyright (C) 2019 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 IDMAP2_INCLUDE_IDMAP2_RESOURCEMAPPING_H_
18 #define IDMAP2_INCLUDE_IDMAP2_RESOURCEMAPPING_H_
19
20 #include <androidfw/ApkAssets.h>
21
22 #include <map>
23 #include <memory>
24 #include <utility>
25
26 #include "idmap2/FabricatedOverlay.h"
27 #include "idmap2/LogInfo.h"
28 #include "idmap2/Policies.h"
29 #include "idmap2/ResourceUtils.h"
30 #include "idmap2/Result.h"
31 #include "idmap2/XmlParser.h"
32
33 using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask;
34
35 namespace android::idmap2 {
36 using TargetResourceMap = std::map<ResourceId, std::variant<ResourceId, TargetValue>>;
37 using OverlayResourceMap = std::map<ResourceId, ResourceId>;
38
39 class ResourceMapping {
40 public:
41 // Creates a ResourceMapping using the target and overlay APKs. Setting enforce_overlayable to
42 // `false` disables all overlayable and policy enforcement: this is intended for backwards
43 // compatibility pre-Q and unit tests.
44 static Result<ResourceMapping> FromContainers(const TargetResourceContainer& target,
45 const OverlayResourceContainer& overlay,
46 const OverlayManifestInfo& overlay_info,
47 const PolicyBitmask& fulfilled_policies,
48 bool enforce_overlayable, LogInfo& log_info);
49
50 // Retrieves the mapping of target resource id to overlay value.
51 WARN_UNUSED const TargetResourceMap& GetTargetToOverlayMap() const;
52
53 // Retrieves the mapping of overlay resource id to target resource id. This allows a reference to
54 // an overlay resource to appear as a reference to its corresponding target resource at runtime.
55 WARN_UNUSED const OverlayResourceMap& GetOverlayToTargetMap() const;
56
57 // Retrieves the offset that was added to the index of inline string overlay values so the indices
58 // do not collide with the indices of the overlay resource table string pool.
59 WARN_UNUSED uint32_t GetStringPoolOffset() const;
60
61 // Retrieves the raw string pool data from the xml referenced in android:resourcesMap.
62 WARN_UNUSED StringPiece GetStringPoolData() const;
63
64 private:
65 ResourceMapping() = default;
66
67 // Maps a target resource id to an overlay resource id or a android::Res_value value.
68 //
69 // If `allow_rewriting_` is true, then the overlay-to-target map will be populated if the target
70 // resource id is mapped to an overlay resource id.
71 Result<Unit> AddMapping(ResourceId target_resource,
72 const std::variant<OverlayData::ResourceIdValue, TargetValue>& value);
73
74 TargetResourceMap target_map_;
75 OverlayResourceMap overlay_map_;
76 uint32_t string_pool_offset_ = 0;
77 uint32_t string_pool_data_length_ = 0;
78 std::unique_ptr<uint8_t[]> string_pool_data_ = nullptr;
79 };
80
GetTargetToOverlayMap()81 inline const TargetResourceMap& ResourceMapping::GetTargetToOverlayMap() const {
82 return target_map_;
83 }
84
GetOverlayToTargetMap()85 inline const OverlayResourceMap& ResourceMapping::GetOverlayToTargetMap() const {
86 return overlay_map_;
87 }
88
GetStringPoolOffset()89 inline uint32_t ResourceMapping::GetStringPoolOffset() const {
90 return string_pool_offset_;
91 }
92
GetStringPoolData()93 inline StringPiece ResourceMapping::GetStringPoolData() const {
94 return StringPiece(reinterpret_cast<const char*>(string_pool_data_.get()),
95 string_pool_data_length_);
96 }
97
98 } // namespace android::idmap2
99
100 #endif // IDMAP2_INCLUDE_IDMAP2_RESOURCEMAPPING_H_
101