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