xref: /aosp_15_r20/frameworks/base/services/incremental/IncrementalService.h (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
1*d57664e9SAndroid Build Coastguard Worker /*
2*d57664e9SAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*d57664e9SAndroid Build Coastguard Worker  *
4*d57664e9SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*d57664e9SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*d57664e9SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*d57664e9SAndroid Build Coastguard Worker  *
8*d57664e9SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*d57664e9SAndroid Build Coastguard Worker  *
10*d57664e9SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*d57664e9SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*d57664e9SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*d57664e9SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*d57664e9SAndroid Build Coastguard Worker  * limitations under the License.
15*d57664e9SAndroid Build Coastguard Worker  */
16*d57664e9SAndroid Build Coastguard Worker 
17*d57664e9SAndroid Build Coastguard Worker #pragma once
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include <android/content/pm/BnDataLoaderStatusListener.h>
20*d57664e9SAndroid Build Coastguard Worker #include <android/content/pm/DataLoaderParamsParcel.h>
21*d57664e9SAndroid Build Coastguard Worker #include <android/content/pm/FileSystemControlParcel.h>
22*d57664e9SAndroid Build Coastguard Worker #include <android/content/pm/IDataLoaderStatusListener.h>
23*d57664e9SAndroid Build Coastguard Worker #include <android/os/incremental/BnIncrementalService.h>
24*d57664e9SAndroid Build Coastguard Worker #include <android/os/incremental/BnIncrementalServiceConnector.h>
25*d57664e9SAndroid Build Coastguard Worker #include <android/os/incremental/BnStorageHealthListener.h>
26*d57664e9SAndroid Build Coastguard Worker #include <android/os/incremental/BnStorageLoadingProgressListener.h>
27*d57664e9SAndroid Build Coastguard Worker #include <android/os/incremental/PerUidReadTimeouts.h>
28*d57664e9SAndroid Build Coastguard Worker #include <android/os/incremental/StorageHealthCheckParams.h>
29*d57664e9SAndroid Build Coastguard Worker #include <binder/IAppOpsCallback.h>
30*d57664e9SAndroid Build Coastguard Worker #include <binder/PersistableBundle.h>
31*d57664e9SAndroid Build Coastguard Worker #include <utils/String16.h>
32*d57664e9SAndroid Build Coastguard Worker #include <utils/StrongPointer.h>
33*d57664e9SAndroid Build Coastguard Worker #include <ziparchive/zip_archive.h>
34*d57664e9SAndroid Build Coastguard Worker 
35*d57664e9SAndroid Build Coastguard Worker #include <atomic>
36*d57664e9SAndroid Build Coastguard Worker #include <chrono>
37*d57664e9SAndroid Build Coastguard Worker #include <condition_variable>
38*d57664e9SAndroid Build Coastguard Worker #include <functional>
39*d57664e9SAndroid Build Coastguard Worker #include <limits>
40*d57664e9SAndroid Build Coastguard Worker #include <map>
41*d57664e9SAndroid Build Coastguard Worker #include <mutex>
42*d57664e9SAndroid Build Coastguard Worker #include <set>
43*d57664e9SAndroid Build Coastguard Worker #include <span>
44*d57664e9SAndroid Build Coastguard Worker #include <string>
45*d57664e9SAndroid Build Coastguard Worker #include <string_view>
46*d57664e9SAndroid Build Coastguard Worker #include <thread>
47*d57664e9SAndroid Build Coastguard Worker #include <unordered_map>
48*d57664e9SAndroid Build Coastguard Worker #include <unordered_set>
49*d57664e9SAndroid Build Coastguard Worker #include <utility>
50*d57664e9SAndroid Build Coastguard Worker #include <vector>
51*d57664e9SAndroid Build Coastguard Worker 
52*d57664e9SAndroid Build Coastguard Worker #include "ServiceWrappers.h"
53*d57664e9SAndroid Build Coastguard Worker #include "incfs.h"
54*d57664e9SAndroid Build Coastguard Worker #include "path.h"
55*d57664e9SAndroid Build Coastguard Worker 
56*d57664e9SAndroid Build Coastguard Worker namespace android::incremental {
57*d57664e9SAndroid Build Coastguard Worker 
58*d57664e9SAndroid Build Coastguard Worker using MountId = int;
59*d57664e9SAndroid Build Coastguard Worker using StorageId = int;
60*d57664e9SAndroid Build Coastguard Worker using FileId = incfs::FileId;
61*d57664e9SAndroid Build Coastguard Worker using BlockIndex = incfs::BlockIndex;
62*d57664e9SAndroid Build Coastguard Worker using RawMetadata = incfs::RawMetadata;
63*d57664e9SAndroid Build Coastguard Worker using Seconds = std::chrono::seconds;
64*d57664e9SAndroid Build Coastguard Worker using BootClockTsUs = uint64_t;
65*d57664e9SAndroid Build Coastguard Worker 
66*d57664e9SAndroid Build Coastguard Worker using IDataLoaderStatusListener = ::android::content::pm::IDataLoaderStatusListener;
67*d57664e9SAndroid Build Coastguard Worker using DataLoaderStatusListener = ::android::sp<IDataLoaderStatusListener>;
68*d57664e9SAndroid Build Coastguard Worker 
69*d57664e9SAndroid Build Coastguard Worker using StorageHealthCheckParams = ::android::os::incremental::StorageHealthCheckParams;
70*d57664e9SAndroid Build Coastguard Worker using IStorageHealthListener = ::android::os::incremental::IStorageHealthListener;
71*d57664e9SAndroid Build Coastguard Worker using StorageHealthListener = ::android::sp<IStorageHealthListener>;
72*d57664e9SAndroid Build Coastguard Worker using IStorageLoadingProgressListener = ::android::os::incremental::IStorageLoadingProgressListener;
73*d57664e9SAndroid Build Coastguard Worker using StorageLoadingProgressListener = ::android::sp<IStorageLoadingProgressListener>;
74*d57664e9SAndroid Build Coastguard Worker 
75*d57664e9SAndroid Build Coastguard Worker using PerUidReadTimeouts = ::android::os::incremental::PerUidReadTimeouts;
76*d57664e9SAndroid Build Coastguard Worker 
77*d57664e9SAndroid Build Coastguard Worker struct IfsState {
78*d57664e9SAndroid Build Coastguard Worker     // If mount is fully loaded.
79*d57664e9SAndroid Build Coastguard Worker     bool fullyLoaded = false;
80*d57664e9SAndroid Build Coastguard Worker     // If read logs are enabled on this mount. Populated only if fullyLoaded == true.
81*d57664e9SAndroid Build Coastguard Worker     bool readLogsEnabled = false;
82*d57664e9SAndroid Build Coastguard Worker     // If there was an error fetching any of the above.
83*d57664e9SAndroid Build Coastguard Worker     bool error = false;
84*d57664e9SAndroid Build Coastguard Worker };
85*d57664e9SAndroid Build Coastguard Worker // Returns true if wants to be called again.
86*d57664e9SAndroid Build Coastguard Worker using IfsStateCallback = std::function<bool(StorageId, IfsState)>;
87*d57664e9SAndroid Build Coastguard Worker 
88*d57664e9SAndroid Build Coastguard Worker class IncrementalService final {
89*d57664e9SAndroid Build Coastguard Worker public:
90*d57664e9SAndroid Build Coastguard Worker     explicit IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir);
91*d57664e9SAndroid Build Coastguard Worker 
92*d57664e9SAndroid Build Coastguard Worker #pragma GCC diagnostic push
93*d57664e9SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
94*d57664e9SAndroid Build Coastguard Worker     ~IncrementalService();
95*d57664e9SAndroid Build Coastguard Worker #pragma GCC diagnostic pop
96*d57664e9SAndroid Build Coastguard Worker 
97*d57664e9SAndroid Build Coastguard Worker     static constexpr StorageId kInvalidStorageId = -1;
98*d57664e9SAndroid Build Coastguard Worker     static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max() - 1;
99*d57664e9SAndroid Build Coastguard Worker     static constexpr StorageId kAllStoragesId = kMaxStorageId + 1;
100*d57664e9SAndroid Build Coastguard Worker 
101*d57664e9SAndroid Build Coastguard Worker     static constexpr BootClockTsUs kMaxBootClockTsUs = std::numeric_limits<BootClockTsUs>::max();
102*d57664e9SAndroid Build Coastguard Worker 
103*d57664e9SAndroid Build Coastguard Worker     enum CreateOptions {
104*d57664e9SAndroid Build Coastguard Worker         TemporaryBind = 1,
105*d57664e9SAndroid Build Coastguard Worker         PermanentBind = 2,
106*d57664e9SAndroid Build Coastguard Worker         CreateNew = 4,
107*d57664e9SAndroid Build Coastguard Worker         OpenExisting = 8,
108*d57664e9SAndroid Build Coastguard Worker 
109*d57664e9SAndroid Build Coastguard Worker         Default = TemporaryBind | CreateNew
110*d57664e9SAndroid Build Coastguard Worker     };
111*d57664e9SAndroid Build Coastguard Worker 
112*d57664e9SAndroid Build Coastguard Worker     enum class BindKind {
113*d57664e9SAndroid Build Coastguard Worker         Temporary = 0,
114*d57664e9SAndroid Build Coastguard Worker         Permanent = 1,
115*d57664e9SAndroid Build Coastguard Worker     };
116*d57664e9SAndroid Build Coastguard Worker 
117*d57664e9SAndroid Build Coastguard Worker     enum StorageFlags {
118*d57664e9SAndroid Build Coastguard Worker         ReadLogsAllowed = 1 << 0,
119*d57664e9SAndroid Build Coastguard Worker         ReadLogsEnabled = 1 << 1,
120*d57664e9SAndroid Build Coastguard Worker         ReadLogsRequested = 1 << 2,
121*d57664e9SAndroid Build Coastguard Worker 
122*d57664e9SAndroid Build Coastguard Worker         ReadTimeoutsEnabled = 1 << 3,
123*d57664e9SAndroid Build Coastguard Worker         ReadTimeoutsRequested = 1 << 4,
124*d57664e9SAndroid Build Coastguard Worker     };
125*d57664e9SAndroid Build Coastguard Worker 
126*d57664e9SAndroid Build Coastguard Worker     struct LoadingProgress {
127*d57664e9SAndroid Build Coastguard Worker         ssize_t filledBlocks;
128*d57664e9SAndroid Build Coastguard Worker         ssize_t totalBlocks;
129*d57664e9SAndroid Build Coastguard Worker 
isErrorLoadingProgress130*d57664e9SAndroid Build Coastguard Worker         bool isError() const { return totalBlocks < 0; }
startedLoadingProgress131*d57664e9SAndroid Build Coastguard Worker         bool started() const { return totalBlocks > 0; }
fullyLoadedLoadingProgress132*d57664e9SAndroid Build Coastguard Worker         bool fullyLoaded() const { return !isError() && (totalBlocks == filledBlocks); }
133*d57664e9SAndroid Build Coastguard Worker 
blocksRemainingOrErrorLoadingProgress134*d57664e9SAndroid Build Coastguard Worker         int blocksRemainingOrError() const {
135*d57664e9SAndroid Build Coastguard Worker             return totalBlocks <= 0 ? totalBlocks : totalBlocks - filledBlocks;
136*d57664e9SAndroid Build Coastguard Worker         }
137*d57664e9SAndroid Build Coastguard Worker 
getProgressLoadingProgress138*d57664e9SAndroid Build Coastguard Worker         float getProgress() const {
139*d57664e9SAndroid Build Coastguard Worker             return totalBlocks < 0
140*d57664e9SAndroid Build Coastguard Worker                     ? totalBlocks
141*d57664e9SAndroid Build Coastguard Worker                     : totalBlocks > 0 ? double(filledBlocks) / double(totalBlocks) : 1.f;
142*d57664e9SAndroid Build Coastguard Worker         }
143*d57664e9SAndroid Build Coastguard Worker     };
144*d57664e9SAndroid Build Coastguard Worker 
145*d57664e9SAndroid Build Coastguard Worker     static FileId idFromMetadata(std::span<const uint8_t> metadata);
idFromMetadata(std::span<const char> metadata)146*d57664e9SAndroid Build Coastguard Worker     static inline FileId idFromMetadata(std::span<const char> metadata) {
147*d57664e9SAndroid Build Coastguard Worker         return idFromMetadata({(const uint8_t*)metadata.data(), metadata.size()});
148*d57664e9SAndroid Build Coastguard Worker     }
149*d57664e9SAndroid Build Coastguard Worker 
150*d57664e9SAndroid Build Coastguard Worker     void onDump(int fd);
151*d57664e9SAndroid Build Coastguard Worker 
152*d57664e9SAndroid Build Coastguard Worker     void onSystemReady();
153*d57664e9SAndroid Build Coastguard Worker 
154*d57664e9SAndroid Build Coastguard Worker     StorageId createStorage(std::string_view mountPoint,
155*d57664e9SAndroid Build Coastguard Worker                             content::pm::DataLoaderParamsParcel dataLoaderParams,
156*d57664e9SAndroid Build Coastguard Worker                             CreateOptions options);
157*d57664e9SAndroid Build Coastguard Worker     StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage,
158*d57664e9SAndroid Build Coastguard Worker                                   CreateOptions options = CreateOptions::Default);
159*d57664e9SAndroid Build Coastguard Worker     StorageId openStorage(std::string_view path);
160*d57664e9SAndroid Build Coastguard Worker 
161*d57664e9SAndroid Build Coastguard Worker     bool startLoading(StorageId storage, content::pm::DataLoaderParamsParcel dataLoaderParams,
162*d57664e9SAndroid Build Coastguard Worker                       DataLoaderStatusListener statusListener,
163*d57664e9SAndroid Build Coastguard Worker                       const StorageHealthCheckParams& healthCheckParams,
164*d57664e9SAndroid Build Coastguard Worker                       StorageHealthListener healthListener,
165*d57664e9SAndroid Build Coastguard Worker                       std::vector<PerUidReadTimeouts> perUidReadTimeouts);
166*d57664e9SAndroid Build Coastguard Worker     void onInstallationComplete(StorageId storage);
167*d57664e9SAndroid Build Coastguard Worker 
168*d57664e9SAndroid Build Coastguard Worker     int bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind);
169*d57664e9SAndroid Build Coastguard Worker     int unbind(StorageId storage, std::string_view target);
170*d57664e9SAndroid Build Coastguard Worker     void deleteStorage(StorageId storage);
171*d57664e9SAndroid Build Coastguard Worker 
172*d57664e9SAndroid Build Coastguard Worker     void disallowReadLogs(StorageId storage);
173*d57664e9SAndroid Build Coastguard Worker     int setStorageParams(StorageId storage, bool enableReadLogs);
174*d57664e9SAndroid Build Coastguard Worker 
175*d57664e9SAndroid Build Coastguard Worker     int makeFile(StorageId storage, std::string_view path, int mode, FileId id,
176*d57664e9SAndroid Build Coastguard Worker                  incfs::NewFileParams params, std::span<const uint8_t> data);
177*d57664e9SAndroid Build Coastguard Worker     int makeDir(StorageId storage, std::string_view path, int mode = 0755);
178*d57664e9SAndroid Build Coastguard Worker     int makeDirs(StorageId storage, std::string_view path, int mode = 0755);
179*d57664e9SAndroid Build Coastguard Worker 
180*d57664e9SAndroid Build Coastguard Worker     int link(StorageId sourceStorageId, std::string_view oldPath, StorageId destStorageId,
181*d57664e9SAndroid Build Coastguard Worker              std::string_view newPath);
182*d57664e9SAndroid Build Coastguard Worker     int unlink(StorageId storage, std::string_view path);
183*d57664e9SAndroid Build Coastguard Worker 
184*d57664e9SAndroid Build Coastguard Worker     incfs::LoadingState isFileFullyLoaded(StorageId storage, std::string_view filePath) const;
185*d57664e9SAndroid Build Coastguard Worker     incfs::LoadingState isMountFullyLoaded(StorageId storage) const;
186*d57664e9SAndroid Build Coastguard Worker 
187*d57664e9SAndroid Build Coastguard Worker     LoadingProgress getLoadingProgress(StorageId storage) const;
188*d57664e9SAndroid Build Coastguard Worker 
189*d57664e9SAndroid Build Coastguard Worker     bool registerLoadingProgressListener(StorageId storage,
190*d57664e9SAndroid Build Coastguard Worker                                          StorageLoadingProgressListener progressListener);
191*d57664e9SAndroid Build Coastguard Worker     bool unregisterLoadingProgressListener(StorageId storage);
192*d57664e9SAndroid Build Coastguard Worker 
193*d57664e9SAndroid Build Coastguard Worker     RawMetadata getMetadata(StorageId storage, std::string_view path) const;
194*d57664e9SAndroid Build Coastguard Worker     RawMetadata getMetadata(StorageId storage, FileId node) const;
195*d57664e9SAndroid Build Coastguard Worker 
196*d57664e9SAndroid Build Coastguard Worker     bool configureNativeBinaries(StorageId storage, std::string_view apkFullPath,
197*d57664e9SAndroid Build Coastguard Worker                                  std::string_view libDirRelativePath, std::string_view abi,
198*d57664e9SAndroid Build Coastguard Worker                                  bool extractNativeLibs);
199*d57664e9SAndroid Build Coastguard Worker     bool waitForNativeBinariesExtraction(StorageId storage);
200*d57664e9SAndroid Build Coastguard Worker 
201*d57664e9SAndroid Build Coastguard Worker     void getMetrics(int32_t storageId, android::os::PersistableBundle* _aidl_return);
202*d57664e9SAndroid Build Coastguard Worker 
203*d57664e9SAndroid Build Coastguard Worker     class AppOpsListener : public android::BnAppOpsCallback {
204*d57664e9SAndroid Build Coastguard Worker     public:
AppOpsListener(IncrementalService & incrementalService,std::string packageName)205*d57664e9SAndroid Build Coastguard Worker         AppOpsListener(IncrementalService& incrementalService, std::string packageName)
206*d57664e9SAndroid Build Coastguard Worker               : incrementalService(incrementalService), packageName(std::move(packageName)) {}
207*d57664e9SAndroid Build Coastguard Worker         void opChanged(int32_t op, const String16& packageName) final;
208*d57664e9SAndroid Build Coastguard Worker 
209*d57664e9SAndroid Build Coastguard Worker     private:
210*d57664e9SAndroid Build Coastguard Worker         IncrementalService& incrementalService;
211*d57664e9SAndroid Build Coastguard Worker         const std::string packageName;
212*d57664e9SAndroid Build Coastguard Worker     };
213*d57664e9SAndroid Build Coastguard Worker 
214*d57664e9SAndroid Build Coastguard Worker     class IncrementalServiceConnector : public os::incremental::BnIncrementalServiceConnector {
215*d57664e9SAndroid Build Coastguard Worker     public:
IncrementalServiceConnector(IncrementalService & incrementalService,int32_t storage)216*d57664e9SAndroid Build Coastguard Worker         IncrementalServiceConnector(IncrementalService& incrementalService, int32_t storage)
217*d57664e9SAndroid Build Coastguard Worker               : incrementalService(incrementalService), storage(storage) {}
218*d57664e9SAndroid Build Coastguard Worker         binder::Status setStorageParams(bool enableReadLogs, int32_t* _aidl_return) final;
219*d57664e9SAndroid Build Coastguard Worker 
220*d57664e9SAndroid Build Coastguard Worker     private:
221*d57664e9SAndroid Build Coastguard Worker         IncrementalService& incrementalService;
222*d57664e9SAndroid Build Coastguard Worker         int32_t const storage;
223*d57664e9SAndroid Build Coastguard Worker     };
224*d57664e9SAndroid Build Coastguard Worker 
225*d57664e9SAndroid Build Coastguard Worker private:
226*d57664e9SAndroid Build Coastguard Worker     struct IncFsMount;
227*d57664e9SAndroid Build Coastguard Worker 
228*d57664e9SAndroid Build Coastguard Worker     class DataLoaderStub : public content::pm::BnDataLoaderStatusListener {
229*d57664e9SAndroid Build Coastguard Worker     public:
230*d57664e9SAndroid Build Coastguard Worker         DataLoaderStub(IncrementalService& service, MountId id,
231*d57664e9SAndroid Build Coastguard Worker                        content::pm::DataLoaderParamsParcel&& params,
232*d57664e9SAndroid Build Coastguard Worker                        content::pm::FileSystemControlParcel&& control,
233*d57664e9SAndroid Build Coastguard Worker                        DataLoaderStatusListener&& statusListener,
234*d57664e9SAndroid Build Coastguard Worker                        const StorageHealthCheckParams& healthCheckParams,
235*d57664e9SAndroid Build Coastguard Worker                        StorageHealthListener&& healthListener, std::string&& healthPath);
236*d57664e9SAndroid Build Coastguard Worker         ~DataLoaderStub();
237*d57664e9SAndroid Build Coastguard Worker         // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will
238*d57664e9SAndroid Build Coastguard Worker         // result in an error.
239*d57664e9SAndroid Build Coastguard Worker         void cleanupResources();
240*d57664e9SAndroid Build Coastguard Worker 
241*d57664e9SAndroid Build Coastguard Worker         bool requestCreate();
242*d57664e9SAndroid Build Coastguard Worker         bool requestStart();
243*d57664e9SAndroid Build Coastguard Worker         bool requestDestroy();
244*d57664e9SAndroid Build Coastguard Worker 
245*d57664e9SAndroid Build Coastguard Worker         void onDump(int fd);
246*d57664e9SAndroid Build Coastguard Worker 
id()247*d57664e9SAndroid Build Coastguard Worker         MountId id() const { return mId.load(std::memory_order_relaxed); }
params()248*d57664e9SAndroid Build Coastguard Worker         const content::pm::DataLoaderParamsParcel& params() const { return mParams; }
249*d57664e9SAndroid Build Coastguard Worker         bool isSystemDataLoader() const;
250*d57664e9SAndroid Build Coastguard Worker         void setHealthListener(const StorageHealthCheckParams& healthCheckParams,
251*d57664e9SAndroid Build Coastguard Worker                                StorageHealthListener&& healthListener);
252*d57664e9SAndroid Build Coastguard Worker         void getMetrics(android::os::PersistableBundle* _aidl_return);
253*d57664e9SAndroid Build Coastguard Worker 
254*d57664e9SAndroid Build Coastguard Worker     private:
255*d57664e9SAndroid Build Coastguard Worker         binder::Status onStatusChanged(MountId mount, int newStatus) final;
256*d57664e9SAndroid Build Coastguard Worker 
257*d57664e9SAndroid Build Coastguard Worker         void setCurrentStatus(int newStatus);
258*d57664e9SAndroid Build Coastguard Worker         void compareAndSetCurrentStatus(int expectedStatus, int newStatus);
259*d57664e9SAndroid Build Coastguard Worker 
260*d57664e9SAndroid Build Coastguard Worker         sp<content::pm::IDataLoader> getDataLoader();
261*d57664e9SAndroid Build Coastguard Worker 
262*d57664e9SAndroid Build Coastguard Worker         bool bind();
263*d57664e9SAndroid Build Coastguard Worker         bool create();
264*d57664e9SAndroid Build Coastguard Worker         bool start();
265*d57664e9SAndroid Build Coastguard Worker         bool destroy();
266*d57664e9SAndroid Build Coastguard Worker 
267*d57664e9SAndroid Build Coastguard Worker         bool setTargetStatus(int status);
268*d57664e9SAndroid Build Coastguard Worker         void setTargetStatusLocked(int status);
269*d57664e9SAndroid Build Coastguard Worker 
270*d57664e9SAndroid Build Coastguard Worker         bool fsmStep();
271*d57664e9SAndroid Build Coastguard Worker 
272*d57664e9SAndroid Build Coastguard Worker         void onHealthStatus(const StorageHealthListener& healthListener, int healthStatus);
273*d57664e9SAndroid Build Coastguard Worker         void updateHealthStatus(bool baseline = false);
274*d57664e9SAndroid Build Coastguard Worker 
isValid()275*d57664e9SAndroid Build Coastguard Worker         bool isValid() const { return id() != kInvalidStorageId; }
276*d57664e9SAndroid Build Coastguard Worker 
277*d57664e9SAndroid Build Coastguard Worker         bool isHealthParamsValid() const;
278*d57664e9SAndroid Build Coastguard Worker 
279*d57664e9SAndroid Build Coastguard Worker         const incfs::UniqueControl& initializeHealthControl();
280*d57664e9SAndroid Build Coastguard Worker         void resetHealthControl();
281*d57664e9SAndroid Build Coastguard Worker 
282*d57664e9SAndroid Build Coastguard Worker         BootClockTsUs getOldestPendingReadTs();
283*d57664e9SAndroid Build Coastguard Worker         BootClockTsUs getOldestTsFromLastPendingReads();
284*d57664e9SAndroid Build Coastguard Worker         Milliseconds elapsedMsSinceKernelTs(TimePoint now, BootClockTsUs kernelTsUs);
285*d57664e9SAndroid Build Coastguard Worker         long elapsedMsSinceOldestPendingRead();
286*d57664e9SAndroid Build Coastguard Worker 
287*d57664e9SAndroid Build Coastguard Worker         // If the stub has to bind to the DL.
288*d57664e9SAndroid Build Coastguard Worker         // Returns {} if bind operation is already in progress.
289*d57664e9SAndroid Build Coastguard Worker         // Or bind delay in ms.
290*d57664e9SAndroid Build Coastguard Worker         std::optional<Milliseconds> needToBind();
291*d57664e9SAndroid Build Coastguard Worker 
292*d57664e9SAndroid Build Coastguard Worker         void registerForPendingReads();
293*d57664e9SAndroid Build Coastguard Worker         void unregisterFromPendingReads();
294*d57664e9SAndroid Build Coastguard Worker 
295*d57664e9SAndroid Build Coastguard Worker         IncrementalService& mService;
296*d57664e9SAndroid Build Coastguard Worker 
297*d57664e9SAndroid Build Coastguard Worker         std::mutex mMutex;
298*d57664e9SAndroid Build Coastguard Worker         std::atomic<MountId> mId = kInvalidStorageId;
299*d57664e9SAndroid Build Coastguard Worker         content::pm::DataLoaderParamsParcel mParams;
300*d57664e9SAndroid Build Coastguard Worker         content::pm::FileSystemControlParcel mControl;
301*d57664e9SAndroid Build Coastguard Worker         DataLoaderStatusListener mStatusListener;
302*d57664e9SAndroid Build Coastguard Worker         StorageHealthListener mHealthListener;
303*d57664e9SAndroid Build Coastguard Worker         std::atomic<int> mHealthStatus = IStorageHealthListener::HEALTH_STATUS_OK;
304*d57664e9SAndroid Build Coastguard Worker 
305*d57664e9SAndroid Build Coastguard Worker         std::condition_variable mStatusCondition;
306*d57664e9SAndroid Build Coastguard Worker         int mCurrentStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
307*d57664e9SAndroid Build Coastguard Worker         TimePoint mCurrentStatusTs = {};
308*d57664e9SAndroid Build Coastguard Worker         int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
309*d57664e9SAndroid Build Coastguard Worker         TimePoint mTargetStatusTs = {};
310*d57664e9SAndroid Build Coastguard Worker 
311*d57664e9SAndroid Build Coastguard Worker         TimePoint mPreviousBindTs = {};
312*d57664e9SAndroid Build Coastguard Worker         Milliseconds mPreviousBindDelay = {};
313*d57664e9SAndroid Build Coastguard Worker 
314*d57664e9SAndroid Build Coastguard Worker         std::string mHealthPath;
315*d57664e9SAndroid Build Coastguard Worker         incfs::UniqueControl mHealthControl;
316*d57664e9SAndroid Build Coastguard Worker         struct {
317*d57664e9SAndroid Build Coastguard Worker             TimePoint userTs;
318*d57664e9SAndroid Build Coastguard Worker             BootClockTsUs kernelTsUs;
319*d57664e9SAndroid Build Coastguard Worker         } mHealthBase = {TimePoint::max(), kMaxBootClockTsUs};
320*d57664e9SAndroid Build Coastguard Worker         StorageHealthCheckParams mHealthCheckParams;
321*d57664e9SAndroid Build Coastguard Worker         std::vector<incfs::ReadInfoWithUid> mLastPendingReads;
322*d57664e9SAndroid Build Coastguard Worker     };
323*d57664e9SAndroid Build Coastguard Worker     using DataLoaderStubPtr = sp<DataLoaderStub>;
324*d57664e9SAndroid Build Coastguard Worker 
325*d57664e9SAndroid Build Coastguard Worker     struct IncFsMount {
326*d57664e9SAndroid Build Coastguard Worker         struct Bind {
327*d57664e9SAndroid Build Coastguard Worker             StorageId storage;
328*d57664e9SAndroid Build Coastguard Worker             std::string savedFilename;
329*d57664e9SAndroid Build Coastguard Worker             std::string sourceDir;
330*d57664e9SAndroid Build Coastguard Worker             BindKind kind;
331*d57664e9SAndroid Build Coastguard Worker         };
332*d57664e9SAndroid Build Coastguard Worker 
333*d57664e9SAndroid Build Coastguard Worker         struct Storage {
334*d57664e9SAndroid Build Coastguard Worker             std::string name;
335*d57664e9SAndroid Build Coastguard Worker         };
336*d57664e9SAndroid Build Coastguard Worker 
337*d57664e9SAndroid Build Coastguard Worker         using Control = incfs::UniqueControl;
338*d57664e9SAndroid Build Coastguard Worker 
339*d57664e9SAndroid Build Coastguard Worker         using BindMap = std::map<std::string, Bind, path::PathLess>;
340*d57664e9SAndroid Build Coastguard Worker         using StorageMap = std::unordered_map<StorageId, Storage>;
341*d57664e9SAndroid Build Coastguard Worker 
342*d57664e9SAndroid Build Coastguard Worker         mutable std::mutex lock;
343*d57664e9SAndroid Build Coastguard Worker         const std::string root;
344*d57664e9SAndroid Build Coastguard Worker         const std::string metricsKey;
345*d57664e9SAndroid Build Coastguard Worker         Control control;
346*d57664e9SAndroid Build Coastguard Worker         /*const*/ MountId mountId;
347*d57664e9SAndroid Build Coastguard Worker         int32_t flags = StorageFlags::ReadLogsAllowed;
348*d57664e9SAndroid Build Coastguard Worker         StorageMap storages;
349*d57664e9SAndroid Build Coastguard Worker         BindMap bindPoints;
350*d57664e9SAndroid Build Coastguard Worker         DataLoaderStubPtr dataLoaderStub;
351*d57664e9SAndroid Build Coastguard Worker         TimePoint startLoadingTs = {};
352*d57664e9SAndroid Build Coastguard Worker         std::atomic<int> nextStorageDirNo{0};
353*d57664e9SAndroid Build Coastguard Worker         const IncrementalService& incrementalService;
354*d57664e9SAndroid Build Coastguard Worker 
IncFsMountIncFsMount355*d57664e9SAndroid Build Coastguard Worker         IncFsMount(std::string root, std::string metricsKey, MountId mountId, Control control,
356*d57664e9SAndroid Build Coastguard Worker                    const IncrementalService& incrementalService)
357*d57664e9SAndroid Build Coastguard Worker               : root(std::move(root)),
358*d57664e9SAndroid Build Coastguard Worker                 metricsKey(std::move(metricsKey)),
359*d57664e9SAndroid Build Coastguard Worker                 control(std::move(control)),
360*d57664e9SAndroid Build Coastguard Worker                 mountId(mountId),
361*d57664e9SAndroid Build Coastguard Worker                 incrementalService(incrementalService) {}
362*d57664e9SAndroid Build Coastguard Worker         IncFsMount(IncFsMount&&) = delete;
363*d57664e9SAndroid Build Coastguard Worker         IncFsMount& operator=(IncFsMount&&) = delete;
364*d57664e9SAndroid Build Coastguard Worker         ~IncFsMount();
365*d57664e9SAndroid Build Coastguard Worker 
366*d57664e9SAndroid Build Coastguard Worker         StorageMap::iterator makeStorage(StorageId id);
367*d57664e9SAndroid Build Coastguard Worker 
disallowReadLogsIncFsMount368*d57664e9SAndroid Build Coastguard Worker         void disallowReadLogs() { flags &= ~StorageFlags::ReadLogsAllowed; }
readLogsAllowedIncFsMount369*d57664e9SAndroid Build Coastguard Worker         int32_t readLogsAllowed() const { return (flags & StorageFlags::ReadLogsAllowed); }
370*d57664e9SAndroid Build Coastguard Worker 
setReadLogsEnabledIncFsMount371*d57664e9SAndroid Build Coastguard Worker         void setReadLogsEnabled(bool value) {
372*d57664e9SAndroid Build Coastguard Worker             return setFlag(StorageFlags::ReadLogsEnabled, value);
373*d57664e9SAndroid Build Coastguard Worker         }
readLogsEnabledIncFsMount374*d57664e9SAndroid Build Coastguard Worker         int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); }
375*d57664e9SAndroid Build Coastguard Worker 
setReadLogsRequestedIncFsMount376*d57664e9SAndroid Build Coastguard Worker         void setReadLogsRequested(bool value) {
377*d57664e9SAndroid Build Coastguard Worker             return setFlag(StorageFlags::ReadLogsRequested, value);
378*d57664e9SAndroid Build Coastguard Worker         }
readLogsRequestedIncFsMount379*d57664e9SAndroid Build Coastguard Worker         int32_t readLogsRequested() const { return (flags & StorageFlags::ReadLogsRequested); }
380*d57664e9SAndroid Build Coastguard Worker 
setReadTimeoutsEnabledIncFsMount381*d57664e9SAndroid Build Coastguard Worker         void setReadTimeoutsEnabled(bool value) {
382*d57664e9SAndroid Build Coastguard Worker             return setFlag(StorageFlags::ReadTimeoutsEnabled, value);
383*d57664e9SAndroid Build Coastguard Worker         }
readTimeoutsEnabledIncFsMount384*d57664e9SAndroid Build Coastguard Worker         int32_t readTimeoutsEnabled() const { return (flags & StorageFlags::ReadTimeoutsEnabled); }
385*d57664e9SAndroid Build Coastguard Worker 
setReadTimeoutsRequestedIncFsMount386*d57664e9SAndroid Build Coastguard Worker         void setReadTimeoutsRequested(bool value) {
387*d57664e9SAndroid Build Coastguard Worker             return setFlag(StorageFlags::ReadTimeoutsRequested, value);
388*d57664e9SAndroid Build Coastguard Worker         }
readTimeoutsRequestedIncFsMount389*d57664e9SAndroid Build Coastguard Worker         int32_t readTimeoutsRequested() const {
390*d57664e9SAndroid Build Coastguard Worker             return (flags & StorageFlags::ReadTimeoutsRequested);
391*d57664e9SAndroid Build Coastguard Worker         }
392*d57664e9SAndroid Build Coastguard Worker 
393*d57664e9SAndroid Build Coastguard Worker         static void cleanupFilesystem(std::string_view root);
394*d57664e9SAndroid Build Coastguard Worker 
395*d57664e9SAndroid Build Coastguard Worker     private:
396*d57664e9SAndroid Build Coastguard Worker         void setFlag(StorageFlags flag, bool value);
397*d57664e9SAndroid Build Coastguard Worker     };
398*d57664e9SAndroid Build Coastguard Worker 
399*d57664e9SAndroid Build Coastguard Worker     using IfsMountPtr = std::shared_ptr<IncFsMount>;
400*d57664e9SAndroid Build Coastguard Worker     using MountMap = std::unordered_map<MountId, IfsMountPtr>;
401*d57664e9SAndroid Build Coastguard Worker     using BindPathMap = std::map<std::string, IncFsMount::BindMap::iterator, path::PathLess>;
402*d57664e9SAndroid Build Coastguard Worker 
403*d57664e9SAndroid Build Coastguard Worker     static bool perfLoggingEnabled();
404*d57664e9SAndroid Build Coastguard Worker 
405*d57664e9SAndroid Build Coastguard Worker     void setUidReadTimeouts(StorageId storage,
406*d57664e9SAndroid Build Coastguard Worker                             std::vector<PerUidReadTimeouts>&& perUidReadTimeouts);
407*d57664e9SAndroid Build Coastguard Worker     void clearUidReadTimeouts(StorageId storage);
408*d57664e9SAndroid Build Coastguard Worker     bool checkUidReadTimeouts(StorageId storage, IfsState state, Clock::time_point timeLimit);
409*d57664e9SAndroid Build Coastguard Worker 
410*d57664e9SAndroid Build Coastguard Worker     std::unordered_set<std::string_view> adoptMountedInstances();
411*d57664e9SAndroid Build Coastguard Worker     void mountExistingImages(const std::unordered_set<std::string_view>& mountedRootNames);
412*d57664e9SAndroid Build Coastguard Worker     bool mountExistingImage(std::string_view root);
413*d57664e9SAndroid Build Coastguard Worker 
414*d57664e9SAndroid Build Coastguard Worker     IfsMountPtr getIfs(StorageId storage) const;
415*d57664e9SAndroid Build Coastguard Worker     const IfsMountPtr& getIfsLocked(StorageId storage) const;
416*d57664e9SAndroid Build Coastguard Worker     int addBindMount(IncFsMount& ifs, StorageId storage, std::string_view storageRoot,
417*d57664e9SAndroid Build Coastguard Worker                      std::string&& source, std::string&& target, BindKind kind,
418*d57664e9SAndroid Build Coastguard Worker                      std::unique_lock<std::mutex>& mainLock);
419*d57664e9SAndroid Build Coastguard Worker 
420*d57664e9SAndroid Build Coastguard Worker     int addBindMountWithMd(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
421*d57664e9SAndroid Build Coastguard Worker                            std::string&& source, std::string&& target, BindKind kind,
422*d57664e9SAndroid Build Coastguard Worker                            std::unique_lock<std::mutex>& mainLock);
423*d57664e9SAndroid Build Coastguard Worker 
424*d57664e9SAndroid Build Coastguard Worker     void addBindMountRecordLocked(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
425*d57664e9SAndroid Build Coastguard Worker                                   std::string&& source, std::string&& target, BindKind kind);
426*d57664e9SAndroid Build Coastguard Worker 
427*d57664e9SAndroid Build Coastguard Worker     bool needStartDataLoaderLocked(IncFsMount& ifs);
428*d57664e9SAndroid Build Coastguard Worker 
429*d57664e9SAndroid Build Coastguard Worker     void prepareDataLoaderLocked(IncFsMount& ifs, content::pm::DataLoaderParamsParcel&& params,
430*d57664e9SAndroid Build Coastguard Worker                                  DataLoaderStatusListener&& statusListener = {},
431*d57664e9SAndroid Build Coastguard Worker                                  const StorageHealthCheckParams& healthCheckParams = {},
432*d57664e9SAndroid Build Coastguard Worker                                  StorageHealthListener&& healthListener = {});
433*d57664e9SAndroid Build Coastguard Worker 
434*d57664e9SAndroid Build Coastguard Worker     BindPathMap::const_iterator findStorageLocked(std::string_view path) const;
435*d57664e9SAndroid Build Coastguard Worker     StorageId findStorageId(std::string_view path) const;
436*d57664e9SAndroid Build Coastguard Worker 
437*d57664e9SAndroid Build Coastguard Worker     void deleteStorage(IncFsMount& ifs);
438*d57664e9SAndroid Build Coastguard Worker     void deleteStorageLocked(IncFsMount& ifs, std::unique_lock<std::mutex>&& ifsLock);
439*d57664e9SAndroid Build Coastguard Worker     MountMap::iterator getStorageSlotLocked();
440*d57664e9SAndroid Build Coastguard Worker     std::string normalizePathToStorage(const IncFsMount& incfs, StorageId storage,
441*d57664e9SAndroid Build Coastguard Worker                                        std::string_view path) const;
442*d57664e9SAndroid Build Coastguard Worker     std::string normalizePathToStorageLocked(const IncFsMount& incfs,
443*d57664e9SAndroid Build Coastguard Worker                                              IncFsMount::StorageMap::const_iterator storageIt,
444*d57664e9SAndroid Build Coastguard Worker                                              std::string_view path) const;
445*d57664e9SAndroid Build Coastguard Worker     int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
446*d57664e9SAndroid Build Coastguard Worker 
447*d57664e9SAndroid Build Coastguard Worker     int disableReadLogsLocked(IncFsMount& ifs);
448*d57664e9SAndroid Build Coastguard Worker     int applyStorageParamsLocked(IncFsMount& ifs);
449*d57664e9SAndroid Build Coastguard Worker 
450*d57664e9SAndroid Build Coastguard Worker     LoadingProgress getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path) const;
451*d57664e9SAndroid Build Coastguard Worker 
452*d57664e9SAndroid Build Coastguard Worker     int setFileContent(const IfsMountPtr& ifs, const incfs::FileId& fileId,
453*d57664e9SAndroid Build Coastguard Worker                        std::string_view debugFilePath, std::span<const uint8_t> data) const;
454*d57664e9SAndroid Build Coastguard Worker 
455*d57664e9SAndroid Build Coastguard Worker     void registerAppOpsCallback(const std::string& packageName);
456*d57664e9SAndroid Build Coastguard Worker     bool unregisterAppOpsCallback(const std::string& packageName);
457*d57664e9SAndroid Build Coastguard Worker     void onAppOpChanged(const std::string& packageName);
458*d57664e9SAndroid Build Coastguard Worker 
459*d57664e9SAndroid Build Coastguard Worker     void runJobProcessing();
460*d57664e9SAndroid Build Coastguard Worker     void extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle zipFile, ZipEntry& entry,
461*d57664e9SAndroid Build Coastguard Worker                         const incfs::FileId& libFileId, std::string_view debugLibPath,
462*d57664e9SAndroid Build Coastguard Worker                         Clock::time_point scheduledTs);
463*d57664e9SAndroid Build Coastguard Worker 
464*d57664e9SAndroid Build Coastguard Worker     void runCmdLooper();
465*d57664e9SAndroid Build Coastguard Worker 
466*d57664e9SAndroid Build Coastguard Worker     bool addTimedJob(TimedQueueWrapper& timedQueue, MountId id, Milliseconds after, Job what);
467*d57664e9SAndroid Build Coastguard Worker     bool removeTimedJobs(TimedQueueWrapper& timedQueue, MountId id);
468*d57664e9SAndroid Build Coastguard Worker 
469*d57664e9SAndroid Build Coastguard Worker     void addIfsStateCallback(StorageId storageId, IfsStateCallback callback);
470*d57664e9SAndroid Build Coastguard Worker     void removeIfsStateCallbacks(StorageId storageId);
471*d57664e9SAndroid Build Coastguard Worker     void processIfsStateCallbacks();
472*d57664e9SAndroid Build Coastguard Worker     void processIfsStateCallbacks(StorageId storageId, std::vector<IfsStateCallback>& callbacks);
473*d57664e9SAndroid Build Coastguard Worker 
474*d57664e9SAndroid Build Coastguard Worker     bool updateLoadingProgress(int32_t storageId,
475*d57664e9SAndroid Build Coastguard Worker                                StorageLoadingProgressListener&& progressListener);
476*d57664e9SAndroid Build Coastguard Worker 
477*d57664e9SAndroid Build Coastguard Worker     void trimReservedSpaceV1(const IncFsMount& ifs);
478*d57664e9SAndroid Build Coastguard Worker     int64_t elapsedUsSinceMonoTs(uint64_t monoTsUs);
479*d57664e9SAndroid Build Coastguard Worker 
480*d57664e9SAndroid Build Coastguard Worker private:
481*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<VoldServiceWrapper> mVold;
482*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager;
483*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<IncFsWrapper> mIncFs;
484*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<AppOpsManagerWrapper> mAppOpsManager;
485*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<JniWrapper> mJni;
486*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<LooperWrapper> mLooper;
487*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<TimedQueueWrapper> mTimedQueue;
488*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<TimedQueueWrapper> mProgressUpdateJobQueue;
489*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<FsWrapper> mFs;
490*d57664e9SAndroid Build Coastguard Worker     const std::unique_ptr<ClockWrapper> mClock;
491*d57664e9SAndroid Build Coastguard Worker     const std::string mIncrementalDir;
492*d57664e9SAndroid Build Coastguard Worker 
493*d57664e9SAndroid Build Coastguard Worker     mutable std::mutex mLock;
494*d57664e9SAndroid Build Coastguard Worker     mutable std::mutex mMountOperationLock;
495*d57664e9SAndroid Build Coastguard Worker     MountMap mMounts;
496*d57664e9SAndroid Build Coastguard Worker     BindPathMap mBindsByPath;
497*d57664e9SAndroid Build Coastguard Worker 
498*d57664e9SAndroid Build Coastguard Worker     std::mutex mCallbacksLock;
499*d57664e9SAndroid Build Coastguard Worker     std::unordered_map<std::string, sp<AppOpsListener>> mCallbackRegistered;
500*d57664e9SAndroid Build Coastguard Worker 
501*d57664e9SAndroid Build Coastguard Worker     using IfsStateCallbacks = std::map<StorageId, std::vector<IfsStateCallback>>;
502*d57664e9SAndroid Build Coastguard Worker     std::mutex mIfsStateCallbacksLock;
503*d57664e9SAndroid Build Coastguard Worker     IfsStateCallbacks mIfsStateCallbacks;
504*d57664e9SAndroid Build Coastguard Worker 
505*d57664e9SAndroid Build Coastguard Worker     std::atomic_bool mSystemReady = false;
506*d57664e9SAndroid Build Coastguard Worker     StorageId mNextId = 0;
507*d57664e9SAndroid Build Coastguard Worker 
508*d57664e9SAndroid Build Coastguard Worker     std::atomic_bool mRunning{true};
509*d57664e9SAndroid Build Coastguard Worker 
510*d57664e9SAndroid Build Coastguard Worker     std::unordered_map<MountId, std::vector<Job>> mJobQueue;
511*d57664e9SAndroid Build Coastguard Worker     MountId mPendingJobsMount = kInvalidStorageId;
512*d57664e9SAndroid Build Coastguard Worker     std::condition_variable mJobCondition;
513*d57664e9SAndroid Build Coastguard Worker     std::mutex mJobMutex;
514*d57664e9SAndroid Build Coastguard Worker     std::thread mJobProcessor;
515*d57664e9SAndroid Build Coastguard Worker 
516*d57664e9SAndroid Build Coastguard Worker     std::thread mCmdLooperThread;
517*d57664e9SAndroid Build Coastguard Worker };
518*d57664e9SAndroid Build Coastguard Worker 
519*d57664e9SAndroid Build Coastguard Worker } // namespace android::incremental
520