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