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 <map> 21 #include <memory> 22 #include <utility> 23 24 #include "androidfw/ApkAssets.h" 25 #include "idmap2/LogInfo.h" 26 #include "idmap2/Policies.h" 27 #include "idmap2/ResourceUtils.h" 28 #include "idmap2/Result.h" 29 #include "idmap2/XmlParser.h" 30 31 using android::idmap2::utils::OverlayManifestInfo; 32 33 using PolicyBitmask = android::ResTable_overlayable_policy_header::PolicyBitmask; 34 35 namespace android::idmap2 { 36 37 struct TargetValue { 38 typedef uint8_t DataType; 39 typedef uint32_t DataValue; 40 DataType data_type; 41 DataValue data_value; 42 }; 43 44 using TargetResourceMap = std::map<ResourceId, TargetValue>; 45 using OverlayResourceMap = std::map<ResourceId, ResourceId>; 46 47 class ResourceMapping { 48 public: 49 // Creates a ResourceMapping using the target and overlay APKs. Setting enforce_overlayable to 50 // `false` disables all overlayable and policy enforcement: this is intended for backwards 51 // compatibility pre-Q and unit tests. 52 static Result<ResourceMapping> FromApkAssets(const ApkAssets& target_apk_assets, 53 const ApkAssets& overlay_apk_assets, 54 const OverlayManifestInfo& overlay_info, 55 const PolicyBitmask& fulfilled_policies, 56 bool enforce_overlayable, LogInfo& log_info); 57 58 // Retrieves the mapping of target resource id to overlay value. GetTargetToOverlayMap()59 inline TargetResourceMap GetTargetToOverlayMap() const { 60 return target_map_; 61 } 62 63 // Retrieves the mapping of overlay resource id to target resource id. This allows a reference to 64 // an overlay resource to appear as a reference to its corresponding target resource at runtime. 65 OverlayResourceMap GetOverlayToTargetMap() const; 66 67 // Retrieves the build-time package id of the target package. GetTargetPackageId()68 inline uint32_t GetTargetPackageId() const { 69 return target_package_id_; 70 } 71 72 // Retrieves the build-time package id of the overlay package. GetOverlayPackageId()73 inline uint32_t GetOverlayPackageId() const { 74 return overlay_package_id_; 75 } 76 77 // Retrieves the offset that was added to the index of inline string overlay values so the indices 78 // do not collide with the indices of the overlay resource table string pool. GetStringPoolOffset()79 inline uint32_t GetStringPoolOffset() const { 80 return string_pool_offset_; 81 } 82 83 // Retrieves the raw string pool data from the xml referenced in android:resourcesMap. GetStringPoolData()84 inline const std::pair<const uint8_t*, uint32_t> GetStringPoolData() const { 85 return std::make_pair(string_pool_data_.get(), string_pool_data_length_); 86 } 87 88 private: 89 ResourceMapping() = default; 90 91 // Apps a mapping of target resource id to the type and value of the data that overlays the 92 // target resource. The data_type is the runtime format of the data value (see 93 // Res_value::dataType). If rewrite_overlay_reference is `true` then references to an overlay 94 // resource should appear as a reference to its corresponding target resource at runtime. 95 Result<Unit> AddMapping(ResourceId target_resource, TargetValue::DataType data_type, 96 TargetValue::DataValue data_value, bool rewrite_overlay_reference); 97 98 // Removes the overlay value mapping for the target resource. 99 void RemoveMapping(ResourceId target_resource); 100 101 // Parses the mapping of target resources to overlay resources to generate a ResourceMapping. 102 static Result<ResourceMapping> CreateResourceMapping(const AssetManager2* target_am, 103 const LoadedPackage* target_package, 104 const LoadedPackage* overlay_package, 105 size_t string_pool_offset, 106 const XmlParser& overlay_parser, 107 LogInfo& log_info); 108 109 // Generates a ResourceMapping that maps target resources to overlay resources by name. To overlay 110 // a target resource, a resource must exist in the overlay with the same type and entry name as 111 // the target resource. 112 static Result<ResourceMapping> CreateResourceMappingLegacy(const AssetManager2* target_am, 113 const AssetManager2* overlay_am, 114 const LoadedPackage* target_package, 115 const LoadedPackage* overlay_package); 116 117 // Removes resources that do not pass policy or overlayable checks of the target package. 118 void FilterOverlayableResources(const AssetManager2* target_am, 119 const LoadedPackage* target_package, 120 const LoadedPackage* overlay_package, 121 const OverlayManifestInfo& overlay_info, 122 const PolicyBitmask& fulfilled_policies, LogInfo& log_info); 123 124 TargetResourceMap target_map_; 125 std::multimap<ResourceId, ResourceId> overlay_map_; 126 127 uint32_t target_package_id_ = 0; 128 uint32_t overlay_package_id_ = 0; 129 uint32_t string_pool_offset_ = 0; 130 uint32_t string_pool_data_length_ = 0; 131 std::unique_ptr<uint8_t[]> string_pool_data_ = nullptr; 132 }; 133 134 } // namespace android::idmap2 135 136 #endif // IDMAP2_INCLUDE_IDMAP2_RESOURCEMAPPING_H_ 137