blob: d8f2c91a971c4903045c326090e3260c9fe16a0f [file] [log] [blame]
Songchun Fan3c82a302019-11-29 14:23:45 -08001/*
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#pragma once
18
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070019#include <android/content/pm/BnDataLoaderStatusListener.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080020#include <android/content/pm/DataLoaderParamsParcel.h>
Alex Buynytskyycca2c112020-05-05 12:48:41 -070021#include <android/content/pm/FileSystemControlParcel.h>
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070022#include <android/content/pm/IDataLoaderStatusListener.h>
23#include <android/os/incremental/BnIncrementalServiceConnector.h>
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070024#include <android/os/incremental/BnStorageHealthListener.h>
Songchun Fana7098592020-09-03 11:45:53 -070025#include <android/os/incremental/BnStorageLoadingProgressListener.h>
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -080026#include <android/os/incremental/PerUidReadTimeouts.h>
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070027#include <android/os/incremental/StorageHealthCheckParams.h>
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070028#include <binder/IAppOpsCallback.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080029#include <utils/String16.h>
30#include <utils/StrongPointer.h>
Yurii Zubrytskyida208012020-04-07 15:35:21 -070031#include <ziparchive/zip_archive.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080032
33#include <atomic>
34#include <chrono>
Yurii Zubrytskyida208012020-04-07 15:35:21 -070035#include <condition_variable>
36#include <functional>
Songchun Fan3c82a302019-11-29 14:23:45 -080037#include <limits>
38#include <map>
39#include <mutex>
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -070040#include <set>
Songchun Fan9b753082020-02-26 13:08:06 -080041#include <span>
Songchun Fan3c82a302019-11-29 14:23:45 -080042#include <string>
43#include <string_view>
Yurii Zubrytskyida208012020-04-07 15:35:21 -070044#include <thread>
Songchun Fan3c82a302019-11-29 14:23:45 -080045#include <unordered_map>
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070046#include <unordered_set>
Songchun Fan3c82a302019-11-29 14:23:45 -080047#include <utility>
48#include <vector>
49
50#include "ServiceWrappers.h"
Songchun Fan3c82a302019-11-29 14:23:45 -080051#include "incfs.h"
52#include "path.h"
53
Songchun Fan3c82a302019-11-29 14:23:45 -080054namespace android::incremental {
55
56using MountId = int;
57using StorageId = int;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080058using FileId = incfs::FileId;
Songchun Fan3c82a302019-11-29 14:23:45 -080059using BlockIndex = incfs::BlockIndex;
60using RawMetadata = incfs::RawMetadata;
Songchun Fan3c82a302019-11-29 14:23:45 -080061using Seconds = std::chrono::seconds;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070062using BootClockTsUs = uint64_t;
Songchun Fan3c82a302019-11-29 14:23:45 -080063
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -070064using IDataLoaderStatusListener = ::android::content::pm::IDataLoaderStatusListener;
65using DataLoaderStatusListener = ::android::sp<IDataLoaderStatusListener>;
Alex Buynytskyy04f73912020-02-10 08:34:18 -080066
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070067using StorageHealthCheckParams = ::android::os::incremental::StorageHealthCheckParams;
68using IStorageHealthListener = ::android::os::incremental::IStorageHealthListener;
69using StorageHealthListener = ::android::sp<IStorageHealthListener>;
Songchun Fana7098592020-09-03 11:45:53 -070070using IStorageLoadingProgressListener = ::android::os::incremental::IStorageLoadingProgressListener;
71using StorageLoadingProgressListener = ::android::sp<IStorageLoadingProgressListener>;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070072
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -080073using PerUidReadTimeouts = ::android::os::incremental::PerUidReadTimeouts;
74
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080075class IncrementalService final {
Songchun Fan3c82a302019-11-29 14:23:45 -080076public:
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -080077 explicit IncrementalService(ServiceManagerWrapper&& sm, std::string_view rootDir);
Songchun Fan3c82a302019-11-29 14:23:45 -080078
79#pragma GCC diagnostic push
80#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
81 ~IncrementalService();
82#pragma GCC diagnostic pop
83
84 static constexpr StorageId kInvalidStorageId = -1;
85 static constexpr StorageId kMaxStorageId = std::numeric_limits<int>::max();
86
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -070087 static constexpr BootClockTsUs kMaxBootClockTsUs = std::numeric_limits<BootClockTsUs>::max();
88
Songchun Fan3c82a302019-11-29 14:23:45 -080089 enum CreateOptions {
90 TemporaryBind = 1,
91 PermanentBind = 2,
92 CreateNew = 4,
93 OpenExisting = 8,
94
95 Default = TemporaryBind | CreateNew
96 };
97
98 enum class BindKind {
99 Temporary = 0,
100 Permanent = 1,
101 };
102
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700103 enum StorageFlags {
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800104 ReadLogsAllowed = 1 << 0,
105 ReadLogsEnabled = 1 << 1,
106 };
107
108 struct LoadingProgress {
109 ssize_t filledBlocks;
110 ssize_t totalBlocks;
111
112 bool isError() const { return totalBlocks < 0; }
113 bool started() const { return totalBlocks > 0; }
114 bool fullyLoaded() const { return !isError() && (totalBlocks == filledBlocks); }
115
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800116 int blocksRemainingOrError() const {
117 return totalBlocks <= 0 ? totalBlocks : totalBlocks - filledBlocks;
118 }
119
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800120 float getProgress() const {
121 return totalBlocks < 0
122 ? totalBlocks
123 : totalBlocks > 0 ? double(filledBlocks) / double(totalBlocks) : 1.f;
124 }
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700125 };
126
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800127 static FileId idFromMetadata(std::span<const uint8_t> metadata);
128 static inline FileId idFromMetadata(std::span<const char> metadata) {
129 return idFromMetadata({(const uint8_t*)metadata.data(), metadata.size()});
130 }
131
Alex Buynytskyy18b07a42020-02-03 20:06:00 -0800132 void onDump(int fd);
133
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700134 void onSystemReady();
Songchun Fan3c82a302019-11-29 14:23:45 -0800135
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700136 StorageId createStorage(std::string_view mountPoint,
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800137 const content::pm::DataLoaderParamsParcel& dataLoaderParams,
138 CreateOptions options);
Songchun Fan3c82a302019-11-29 14:23:45 -0800139 StorageId createLinkedStorage(std::string_view mountPoint, StorageId linkedStorage,
140 CreateOptions options = CreateOptions::Default);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800141 StorageId openStorage(std::string_view path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800142
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800143 bool startLoading(StorageId storage, content::pm::DataLoaderParamsParcel&& dataLoaderParams,
144 const DataLoaderStatusListener& statusListener,
145 StorageHealthCheckParams&& healthCheckParams,
146 const StorageHealthListener& healthListener,
147 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts);
148
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800149 int bind(StorageId storage, std::string_view source, std::string_view target, BindKind kind);
Songchun Fan3c82a302019-11-29 14:23:45 -0800150 int unbind(StorageId storage, std::string_view target);
151 void deleteStorage(StorageId storage);
152
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800153 void disallowReadLogs(StorageId storage);
Alex Buynytskyy5e860ba2020-03-31 15:30:21 -0700154 int setStorageParams(StorageId storage, bool enableReadLogs);
155
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800156 int makeFile(StorageId storage, std::string_view path, int mode, FileId id,
Alex Buynytskyyb39d13e2020-09-12 16:12:36 -0700157 incfs::NewFileParams params, std::span<const uint8_t> data);
Songchun Fan96100932020-02-03 19:20:58 -0800158 int makeDir(StorageId storage, std::string_view path, int mode = 0755);
159 int makeDirs(StorageId storage, std::string_view path, int mode = 0755);
Songchun Fan3c82a302019-11-29 14:23:45 -0800160
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800161 int link(StorageId sourceStorageId, std::string_view oldPath, StorageId destStorageId,
162 std::string_view newPath);
163 int unlink(StorageId storage, std::string_view path);
Songchun Fan3c82a302019-11-29 14:23:45 -0800164
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800165 int isFileFullyLoaded(StorageId storage, std::string_view filePath) const;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800166
167 LoadingProgress getLoadingProgress(StorageId storage, bool stopOnFirstIncomplete) const;
168
Songchun Fana7098592020-09-03 11:45:53 -0700169 bool registerLoadingProgressListener(StorageId storage,
170 const StorageLoadingProgressListener& progressListener);
171 bool unregisterLoadingProgressListener(StorageId storage);
Songchun Fan2570ec02020-10-08 17:22:33 -0700172 bool registerStorageHealthListener(StorageId storage,
173 StorageHealthCheckParams&& healthCheckParams,
174 const StorageHealthListener& healthListener);
175 void unregisterStorageHealthListener(StorageId storage);
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700176 RawMetadata getMetadata(StorageId storage, std::string_view path) const;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800177 RawMetadata getMetadata(StorageId storage, FileId node) const;
Songchun Fan3c82a302019-11-29 14:23:45 -0800178
Songchun Fan0f8b6fe2020-02-05 17:41:25 -0800179 bool configureNativeBinaries(StorageId storage, std::string_view apkFullPath,
Songchun Fan14f6c3c2020-05-21 18:19:07 -0700180 std::string_view libDirRelativePath, std::string_view abi,
181 bool extractNativeLibs);
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700182 bool waitForNativeBinariesExtraction(StorageId storage);
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700183
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700184 class AppOpsListener : public android::BnAppOpsCallback {
185 public:
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700186 AppOpsListener(IncrementalService& incrementalService, std::string packageName)
187 : incrementalService(incrementalService), packageName(std::move(packageName)) {}
Alex Buynytskyyf4156792020-04-07 14:26:55 -0700188 void opChanged(int32_t op, const String16& packageName) final;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700189
190 private:
191 IncrementalService& incrementalService;
192 const std::string packageName;
193 };
194
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700195 class IncrementalServiceConnector : public os::incremental::BnIncrementalServiceConnector {
Alex Buynytskyyf4156792020-04-07 14:26:55 -0700196 public:
197 IncrementalServiceConnector(IncrementalService& incrementalService, int32_t storage)
Alex Buynytskyy5f9e3a02020-04-07 21:13:41 -0700198 : incrementalService(incrementalService), storage(storage) {}
Alex Buynytskyyf4156792020-04-07 14:26:55 -0700199 binder::Status setStorageParams(bool enableReadLogs, int32_t* _aidl_return) final;
200
201 private:
202 IncrementalService& incrementalService;
Alex Buynytskyy5f9e3a02020-04-07 21:13:41 -0700203 int32_t const storage;
Alex Buynytskyyf4156792020-04-07 14:26:55 -0700204 };
205
Songchun Fan3c82a302019-11-29 14:23:45 -0800206private:
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700207 struct IncFsMount;
208
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700209 class DataLoaderStub : public content::pm::BnDataLoaderStatusListener {
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700210 public:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700211 DataLoaderStub(IncrementalService& service, MountId id,
212 content::pm::DataLoaderParamsParcel&& params,
213 content::pm::FileSystemControlParcel&& control,
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700214 const DataLoaderStatusListener* statusListener,
215 StorageHealthCheckParams&& healthCheckParams,
216 const StorageHealthListener* healthListener, std::string&& healthPath);
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700217 ~DataLoaderStub();
Alex Buynytskyy9a54579a2020-04-17 15:34:47 -0700218 // Cleans up the internal state and invalidates DataLoaderStub. Any subsequent calls will
219 // result in an error.
220 void cleanupResources();
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700221
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700222 bool requestCreate();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700223 bool requestStart();
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700224 bool requestDestroy();
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700225
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700226 void onDump(int fd);
227
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700228 MountId id() const { return mId.load(std::memory_order_relaxed); }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700229 const content::pm::DataLoaderParamsParcel& params() const { return mParams; }
Songchun Fan2570ec02020-10-08 17:22:33 -0700230 void setHealthListener(StorageHealthCheckParams&& healthCheckParams,
231 const StorageHealthListener* healthListener);
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700232
233 private:
234 binder::Status onStatusChanged(MountId mount, int newStatus) final;
Songchun Fan33093982020-09-10 13:12:39 -0700235 binder::Status reportStreamHealth(MountId mount, int newStatus) final;
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700236
Alex Buynytskyy060c9d62021-02-18 20:55:17 -0800237 void setCurrentStatus(int newStatus);
238
Alex Buynytskyy0bdbccf2020-04-23 20:36:42 -0700239 sp<content::pm::IDataLoader> getDataLoader();
Alex Buynytskyy9a54579a2020-04-17 15:34:47 -0700240
Alex Buynytskyyea1390f2020-04-22 16:08:50 -0700241 bool bind();
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700242 bool create();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700243 bool start();
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700244 bool destroy();
245
246 bool setTargetStatus(int status);
Alex Buynytskyy7e0a1a82020-04-27 17:06:10 -0700247 void setTargetStatusLocked(int status);
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700248
249 bool fsmStep();
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700250
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700251 void onHealthStatus(StorageHealthListener healthListener, int healthStatus);
252 void updateHealthStatus(bool baseline = false);
253
254 bool isValid() const { return id() != kInvalidStorageId; }
255
256 bool isHealthParamsValid() const;
257
258 const incfs::UniqueControl& initializeHealthControl();
259 void resetHealthControl();
260
261 BootClockTsUs getOldestPendingReadTs();
262
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800263 Milliseconds updateBindDelay();
264
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700265 void registerForPendingReads();
266 void unregisterFromPendingReads();
Alex Buynytskyyd0855a32020-05-07 18:40:51 -0700267
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700268 IncrementalService& mService;
Alex Buynytskyyb0ea4482020-05-04 18:39:58 -0700269
270 std::mutex mMutex;
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700271 std::atomic<MountId> mId = kInvalidStorageId;
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700272 content::pm::DataLoaderParamsParcel mParams;
273 content::pm::FileSystemControlParcel mControl;
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700274 DataLoaderStatusListener mStatusListener;
275 StorageHealthListener mHealthListener;
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700276
Alex Buynytskyy0b202662020-04-13 09:53:04 -0700277 std::condition_variable mStatusCondition;
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700278 int mCurrentStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
279 int mTargetStatus = content::pm::IDataLoaderStatusListener::DATA_LOADER_DESTROYED;
Alex Buynytskyyab65cb12020-04-17 10:01:47 -0700280 TimePoint mTargetStatusTs = {};
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700281
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800282 TimePoint mPreviousBindTs = {};
283 Milliseconds mPreviousBindDelay = {};
284
Alex Buynytskyyd0855a32020-05-07 18:40:51 -0700285 std::string mHealthPath;
286 incfs::UniqueControl mHealthControl;
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700287 struct {
288 TimePoint userTs;
289 BootClockTsUs kernelTsUs;
290 } mHealthBase = {TimePoint::max(), kMaxBootClockTsUs};
291 StorageHealthCheckParams mHealthCheckParams;
Songchun Fan2570ec02020-10-08 17:22:33 -0700292 int mStreamStatus = content::pm::IDataLoaderStatusListener::STREAM_HEALTHY;
Songchun Fan6944f1e2020-11-06 15:24:24 -0800293 std::vector<incfs::ReadInfo> mLastPendingReads;
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700294 };
295 using DataLoaderStubPtr = sp<DataLoaderStub>;
296
Songchun Fan3c82a302019-11-29 14:23:45 -0800297 struct IncFsMount {
298 struct Bind {
299 StorageId storage;
300 std::string savedFilename;
301 std::string sourceDir;
302 BindKind kind;
303 };
304
305 struct Storage {
306 std::string name;
Songchun Fan3c82a302019-11-29 14:23:45 -0800307 };
308
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800309 using Control = incfs::UniqueControl;
Songchun Fan3c82a302019-11-29 14:23:45 -0800310
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700311 using BindMap = std::map<std::string, Bind, path::PathLess>;
Songchun Fan3c82a302019-11-29 14:23:45 -0800312 using StorageMap = std::unordered_map<StorageId, Storage>;
313
314 mutable std::mutex lock;
315 const std::string root;
316 Control control;
317 /*const*/ MountId mountId;
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800318 int32_t flags = StorageFlags::ReadLogsAllowed;
Songchun Fan3c82a302019-11-29 14:23:45 -0800319 StorageMap storages;
320 BindMap bindPoints;
Alex Buynytskyy0ea4ff42020-04-09 17:25:42 -0700321 DataLoaderStubPtr dataLoaderStub;
Songchun Fan3c82a302019-11-29 14:23:45 -0800322 std::atomic<int> nextStorageDirNo{0};
Songchun Fan3c82a302019-11-29 14:23:45 -0800323 const IncrementalService& incrementalService;
324
325 IncFsMount(std::string root, MountId mountId, Control control,
326 const IncrementalService& incrementalService)
327 : root(std::move(root)),
328 control(std::move(control)),
329 mountId(mountId),
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700330 incrementalService(incrementalService) {}
Songchun Fan3c82a302019-11-29 14:23:45 -0800331 IncFsMount(IncFsMount&&) = delete;
332 IncFsMount& operator=(IncFsMount&&) = delete;
333 ~IncFsMount();
334
335 StorageMap::iterator makeStorage(StorageId id);
336
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800337 void disallowReadLogs() { flags &= ~StorageFlags::ReadLogsAllowed; }
338 int32_t readLogsAllowed() const { return (flags & StorageFlags::ReadLogsAllowed); }
339
340 void setReadLogsEnabled(bool value) {
341 if (value)
342 flags |= StorageFlags::ReadLogsEnabled;
343 else
344 flags &= ~StorageFlags::ReadLogsEnabled;
345 }
Alex Buynytskyy3697d9e2020-06-06 20:15:58 -0700346 int32_t readLogsEnabled() const { return (flags & StorageFlags::ReadLogsEnabled); }
347
Songchun Fan3c82a302019-11-29 14:23:45 -0800348 static void cleanupFilesystem(std::string_view root);
349 };
350
351 using IfsMountPtr = std::shared_ptr<IncFsMount>;
352 using MountMap = std::unordered_map<MountId, IfsMountPtr>;
353 using BindPathMap = std::map<std::string, IncFsMount::BindMap::iterator, path::PathLess>;
354
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700355 static bool perfLoggingEnabled();
356
Alex Buynytskyyaa8e95e2020-12-14 21:50:04 -0800357 void setUidReadTimeouts(StorageId storage,
358 const std::vector<PerUidReadTimeouts>& perUidReadTimeouts);
359 void clearUidReadTimeouts(StorageId storage);
360 void updateUidReadTimeouts(StorageId storage, Clock::time_point timeLimit);
361
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700362 std::unordered_set<std::string_view> adoptMountedInstances();
363 void mountExistingImages(const std::unordered_set<std::string_view>& mountedRootNames);
Yurii Zubrytskyi107ae352020-04-03 13:12:51 -0700364 bool mountExistingImage(std::string_view root);
Songchun Fan3c82a302019-11-29 14:23:45 -0800365
366 IfsMountPtr getIfs(StorageId storage) const;
367 const IfsMountPtr& getIfsLocked(StorageId storage) const;
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800368 int addBindMount(IncFsMount& ifs, StorageId storage, std::string_view storageRoot,
369 std::string&& source, std::string&& target, BindKind kind,
370 std::unique_lock<std::mutex>& mainLock);
Songchun Fan3c82a302019-11-29 14:23:45 -0800371
372 int addBindMountWithMd(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800373 std::string&& source, std::string&& target, BindKind kind,
Songchun Fan3c82a302019-11-29 14:23:45 -0800374 std::unique_lock<std::mutex>& mainLock);
375
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700376 void addBindMountRecordLocked(IncFsMount& ifs, StorageId storage, std::string&& metadataName,
377 std::string&& source, std::string&& target, BindKind kind);
378
Alex Buynytskyyb19ee3e2021-02-06 20:31:43 -0800379 bool needStartDataLoaderLocked(IncFsMount& ifs);
380
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700381 DataLoaderStubPtr prepareDataLoader(IncFsMount& ifs,
382 content::pm::DataLoaderParamsParcel&& params,
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700383 const DataLoaderStatusListener* statusListener = nullptr,
384 StorageHealthCheckParams&& healthCheckParams = {},
385 const StorageHealthListener* healthListener = nullptr);
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700386 void prepareDataLoaderLocked(IncFsMount& ifs, content::pm::DataLoaderParamsParcel&& params,
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700387 const DataLoaderStatusListener* statusListener = nullptr,
388 StorageHealthCheckParams&& healthCheckParams = {},
389 const StorageHealthListener* healthListener = nullptr);
Alex Buynytskyybf1c0632020-03-10 15:49:29 -0700390
Songchun Fan3c82a302019-11-29 14:23:45 -0800391 BindPathMap::const_iterator findStorageLocked(std::string_view path) const;
392 StorageId findStorageId(std::string_view path) const;
393
394 void deleteStorage(IncFsMount& ifs);
395 void deleteStorageLocked(IncFsMount& ifs, std::unique_lock<std::mutex>&& ifsLock);
396 MountMap::iterator getStorageSlotLocked();
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700397 std::string normalizePathToStorage(const IncFsMount& incfs, StorageId storage,
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700398 std::string_view path) const;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700399 std::string normalizePathToStorageLocked(const IncFsMount& incfs,
400 IncFsMount::StorageMap::const_iterator storageIt,
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700401 std::string_view path) const;
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700402 int makeDirs(const IncFsMount& ifs, StorageId storageId, std::string_view path, int mode);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700403 binder::Status applyStorageParams(IncFsMount& ifs, bool enableReadLogs);
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700404
Alex Buynytskyybc0a7e62020-08-25 12:45:22 -0700405 int isFileFullyLoadedFromPath(const IncFsMount& ifs, std::string_view filePath) const;
Alex Buynytskyy07694ed2021-01-27 06:58:55 -0800406 LoadingProgress getLoadingProgressFromPath(const IncFsMount& ifs, std::string_view path,
407 bool stopOnFirstIncomplete) const;
Songchun Fan374f7652020-08-20 08:40:29 -0700408
Alex Buynytskyyb39d13e2020-09-12 16:12:36 -0700409 int setFileContent(const IfsMountPtr& ifs, const incfs::FileId& fileId,
410 std::string_view debugFilePath, std::span<const uint8_t> data) const;
411
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700412 void registerAppOpsCallback(const std::string& packageName);
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700413 bool unregisterAppOpsCallback(const std::string& packageName);
414 void onAppOpChanged(const std::string& packageName);
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700415
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700416 void runJobProcessing();
417 void extractZipFile(const IfsMountPtr& ifs, ZipArchiveHandle zipFile, ZipEntry& entry,
Alex Buynytskyyb39d13e2020-09-12 16:12:36 -0700418 const incfs::FileId& libFileId, std::string_view debugLibPath,
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700419 Clock::time_point scheduledTs);
420
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700421 void runCmdLooper();
422
Songchun Fana7098592020-09-03 11:45:53 -0700423 bool addTimedJob(TimedQueueWrapper& timedQueue, MountId id, Milliseconds after, Job what);
424 bool removeTimedJobs(TimedQueueWrapper& timedQueue, MountId id);
425 bool updateLoadingProgress(int32_t storageId,
426 const StorageLoadingProgressListener& progressListener);
Alex Buynytskyy4760d8f2020-05-08 16:18:52 -0700427
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700428private:
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700429 const std::unique_ptr<VoldServiceWrapper> mVold;
430 const std::unique_ptr<DataLoaderManagerWrapper> mDataLoaderManager;
431 const std::unique_ptr<IncFsWrapper> mIncFs;
432 const std::unique_ptr<AppOpsManagerWrapper> mAppOpsManager;
433 const std::unique_ptr<JniWrapper> mJni;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700434 const std::unique_ptr<LooperWrapper> mLooper;
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700435 const std::unique_ptr<TimedQueueWrapper> mTimedQueue;
Songchun Fana7098592020-09-03 11:45:53 -0700436 const std::unique_ptr<TimedQueueWrapper> mProgressUpdateJobQueue;
Songchun Fan374f7652020-08-20 08:40:29 -0700437 const std::unique_ptr<FsWrapper> mFs;
Songchun Fan3c82a302019-11-29 14:23:45 -0800438 const std::string mIncrementalDir;
439
440 mutable std::mutex mLock;
441 mutable std::mutex mMountOperationLock;
442 MountMap mMounts;
443 BindPathMap mBindsByPath;
444
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700445 std::mutex mCallbacksLock;
Alex Buynytskyy1d892162020-04-03 23:00:19 -0700446 std::map<std::string, sp<AppOpsListener>> mCallbackRegistered;
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700447
Songchun Fan3c82a302019-11-29 14:23:45 -0800448 std::atomic_bool mSystemReady = false;
449 StorageId mNextId = 0;
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700450
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700451 std::atomic_bool mRunning{true};
452
Yurii Zubrytskyi721ac4d2020-04-13 11:34:32 -0700453 std::unordered_map<MountId, std::vector<Job>> mJobQueue;
454 MountId mPendingJobsMount = kInvalidStorageId;
Yurii Zubrytskyida208012020-04-07 15:35:21 -0700455 std::condition_variable mJobCondition;
456 std::mutex mJobMutex;
457 std::thread mJobProcessor;
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700458
459 std::thread mCmdLooperThread;
Songchun Fan3c82a302019-11-29 14:23:45 -0800460};
461
462} // namespace android::incremental