xref: /aosp_15_r20/frameworks/base/libs/androidfw/include/androidfw/ApkAssets.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1 /*
2  * Copyright (C) 2016 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 APKASSETS_H_
18 #define APKASSETS_H_
19 
20 #include <utils/RefBase.h>
21 
22 #include <memory>
23 #include <string>
24 
25 #include "android-base/macros.h"
26 #include "android-base/unique_fd.h"
27 #include "androidfw/Asset.h"
28 #include "androidfw/AssetsProvider.h"
29 #include "androidfw/Idmap.h"
30 #include "androidfw/LoadedArsc.h"
31 #include "androidfw/misc.h"
32 
33 namespace android {
34 
35 class ApkAssets;
36 
37 using ApkAssetsPtr = sp<ApkAssets>;
38 
39 // Holds an APK.
40 class ApkAssets : public RefBase {
41  public:
42   // Creates an ApkAssets from a path on device.
43   static ApkAssetsPtr Load(const std::string& path, package_property_t flags = 0U);
44 
45   // Creates an ApkAssets from an open file descriptor.
46   static ApkAssetsPtr LoadFromFd(base::unique_fd fd, const std::string& debug_name,
47                                  package_property_t flags = 0U, off64_t offset = 0,
48                                  off64_t len = AssetsProvider::kUnknownLength);
49 
50   //
51   // Creates an ApkAssets from an AssetProvider.
52   // The ApkAssets will take care of destroying the AssetsProvider when it is destroyed;
53   // the original argument is not moved from if loading fails.
54   //
55   // Note: this function takes care of the case when you pass a move(unique_ptr<Derived>)
56   //    that would create a temporary unique_ptr<AssetsProvider> by moving your pointer into
57   //    it before the function call, making it impossible to not move from the parameter
58   //    on loading failure. The two overloads take care of moving the pointer back if needed.
59   //
60 
61   template <class T>
62   static ApkAssetsPtr Load(std::unique_ptr<T>&& assets, package_property_t flags = 0U)
requires(std::is_same_v<T,AssetsProvider>)63       requires(std::is_same_v<T, AssetsProvider>) {
64     return LoadImpl(std::move(assets), flags);
65   }
66 
67   template <class T>
68   static ApkAssetsPtr Load(std::unique_ptr<T>&& assets, package_property_t flags = 0U)
69       requires(!std::is_same_v<T, AssetsProvider> && std::is_base_of_v<AssetsProvider, T>) {
70     std::unique_ptr<AssetsProvider> base_assets(std::move(assets));
71     auto res = LoadImpl(std::move(base_assets), flags);
72     if (!res) {
73       assets.reset(static_cast<T*>(base_assets.release()));
74     }
75     return res;
76   }
77 
78   // Creates an ApkAssets from the given asset file representing a resources.arsc.
79   static ApkAssetsPtr LoadTable(std::unique_ptr<Asset>&& resources_asset,
80                                 std::unique_ptr<AssetsProvider>&& assets,
81                                 package_property_t flags = 0U);
82 
83   // Creates an ApkAssets from an IDMAP, which contains the original APK path, and the overlay
84   // data.
85   static ApkAssetsPtr LoadOverlay(const std::string& idmap_path, package_property_t flags = 0U);
86 
87   // Path to the contents of the ApkAssets on disk. The path could represent an APk, a directory,
88   // or some other file type.
89   std::optional<std::string_view> GetPath() const;
90 
91   const std::string& GetDebugName() const;
92 
GetAssetsProvider()93   const AssetsProvider* GetAssetsProvider() const {
94     return assets_provider_.get();
95   }
96 
97   // This is never nullptr.
GetLoadedArsc()98   const LoadedArsc* GetLoadedArsc() const {
99     return loaded_arsc_.get();
100   }
101 
GetLoadedIdmap()102   const LoadedIdmap* GetLoadedIdmap() const {
103     return loaded_idmap_.get();
104   }
105 
IsLoader()106   bool IsLoader() const {
107     return (property_flags_ & PROPERTY_LOADER) != 0;
108   }
109 
IsOverlay()110   bool IsOverlay() const {
111     return loaded_idmap_ != nullptr;
112   }
113 
114   // Returns whether the resources.arsc is allocated in RAM (not mmapped).
IsTableAllocated()115   bool IsTableAllocated() const {
116     return resources_asset_ != nullptr && resources_asset_->isAllocated();
117   }
118 
119   bool IsUpToDate() const;
120 
121   // DANGER!
122   // This is a destructive method that rips the assets provider out of ApkAssets object.
123   // It is only useful when one knows this assets object can't be used anymore, and they
124   // need the underlying assets provider back (e.g. when initialization fails for some
125   // reason).
TakeAssetsProvider()126   std::unique_ptr<AssetsProvider> TakeAssetsProvider() && {
127     return std::move(assets_provider_);
128   }
129 
130  private:
131   static ApkAssetsPtr LoadImpl(std::unique_ptr<AssetsProvider>&& assets,
132                                package_property_t property_flags,
133                                std::unique_ptr<Asset>&& idmap_asset,
134                                std::unique_ptr<LoadedIdmap>&& loaded_idmap);
135 
136   static ApkAssetsPtr LoadImpl(std::unique_ptr<Asset>&& resources_asset,
137                                std::unique_ptr<AssetsProvider>&& assets,
138                                package_property_t property_flags,
139                                std::unique_ptr<Asset>&& idmap_asset,
140                                std::unique_ptr<LoadedIdmap>&& loaded_idmap);
141 
142   static ApkAssetsPtr LoadImpl(std::unique_ptr<AssetsProvider>&& assets,
143                                package_property_t flags = 0U);
144 
145   // Allows us to make it possible to call make_shared from inside the class but still keeps the
146   // ctor 'private' for all means and purposes.
147   struct PrivateConstructorUtil {
148     explicit PrivateConstructorUtil() = default;
149   };
150 
151  public:
152   ApkAssets(PrivateConstructorUtil, std::unique_ptr<Asset> resources_asset,
153             std::unique_ptr<LoadedArsc> loaded_arsc, std::unique_ptr<AssetsProvider> assets,
154             package_property_t property_flags, std::unique_ptr<Asset> idmap_asset,
155             std::unique_ptr<LoadedIdmap> loaded_idmap);
156 
157   std::unique_ptr<Asset> resources_asset_;
158   std::unique_ptr<LoadedArsc> loaded_arsc_;
159 
160   std::unique_ptr<AssetsProvider> assets_provider_;
161   package_property_t property_flags_ = 0U;
162 
163   std::unique_ptr<Asset> idmap_asset_;
164   std::unique_ptr<LoadedIdmap> loaded_idmap_;
165 };
166 
167 } // namespace android
168 
169 #endif // APKASSETS_H_