1 /*
2  * Copyright (C) 2017 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 IDMAP_H_
18 #define IDMAP_H_
19 
20 #include <memory>
21 #include <string>
22 #include <unordered_map>
23 
24 #include "android-base/macros.h"
25 
26 #include "androidfw/StringPiece.h"
27 
28 namespace android {
29 
30 struct Idmap_header;
31 struct IdmapEntry_header;
32 
33 // Represents a loaded/parsed IDMAP for a Runtime Resource Overlay (RRO).
34 // An RRO and its target APK have different resource IDs assigned to their resources. Overlaying
35 // a resource is done by resource name. An IDMAP is a generated mapping between the resource IDs
36 // of the RRO and the target APK for each resource with the same name.
37 // A LoadedIdmap can be set alongside the overlay's LoadedArsc to allow the overlay ApkAssets to
38 // masquerade as the target ApkAssets resources.
39 class LoadedIdmap {
40  public:
41   // Loads an IDMAP from a chunk of memory. Returns nullptr if the IDMAP data was malformed.
42   static std::unique_ptr<const LoadedIdmap> Load(const StringPiece& idmap_data);
43 
44   // Performs a lookup of the expected entry ID for the given IDMAP entry header.
45   // Returns true if the mapping exists and fills `output_entry_id` with the result.
46   static bool Lookup(const IdmapEntry_header* header, uint16_t input_entry_id,
47                      uint16_t* output_entry_id);
48 
49   // Returns the package ID for which this overlay should apply.
50   uint8_t TargetPackageId() const;
51 
52   // Returns the path to the RRO (Runtime Resource Overlay) APK for which this IDMAP was generated.
OverlayApkPath()53   inline const std::string& OverlayApkPath() const {
54     return overlay_apk_path_;
55   }
56 
57   // Returns the mapping of target entry ID to overlay entry ID for the given target type.
58   const IdmapEntry_header* GetEntryMapForType(uint8_t type_id) const;
59 
60  protected:
61   // Exposed as protected so that tests can subclass and mock this class out.
62   LoadedIdmap() = default;
63 
64   const Idmap_header* header_ = nullptr;
65   std::string overlay_apk_path_;
66   std::unordered_map<uint8_t, const IdmapEntry_header*> type_map_;
67 
68  private:
69   DISALLOW_COPY_AND_ASSIGN(LoadedIdmap);
70 
71   explicit LoadedIdmap(const Idmap_header* header);
72 };
73 
74 }  // namespace android
75 
76 #endif  // IDMAP_H_
77