/* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace android::incremental { using Clock = std::chrono::steady_clock; using TimePoint = std::chrono::time_point; using Milliseconds = std::chrono::milliseconds; using Job = std::function; // --- Wrapper interfaces --- using MountId = int32_t; class VoldServiceWrapper { public: virtual ~VoldServiceWrapper() = default; virtual binder::Status mountIncFs( const std::string& backingPath, const std::string& targetDir, int32_t flags, const std::string& sysfsName, os::incremental::IncrementalFileSystemControlParcel* result) const = 0; virtual binder::Status unmountIncFs(const std::string& dir) const = 0; virtual binder::Status bindMount(const std::string& sourceDir, const std::string& targetDir) const = 0; virtual binder::Status setIncFsMountOptions( const os::incremental::IncrementalFileSystemControlParcel& control, bool enableReadLogs, bool enableReadTimeouts, const std::string& sysfsName) const = 0; }; class DataLoaderManagerWrapper { public: virtual ~DataLoaderManagerWrapper() = default; virtual binder::Status bindToDataLoader( MountId mountId, const content::pm::DataLoaderParamsParcel& params, int bindDelayMs, const sp& listener, bool* result) const = 0; virtual binder::Status getDataLoader(MountId mountId, sp* result) const = 0; virtual binder::Status unbindFromDataLoader(MountId mountId) const = 0; }; class IncFsWrapper { public: using Control = incfs::Control; using FileId = incfs::FileId; using ErrorCode = incfs::ErrorCode; using UniqueFd = incfs::UniqueFd; using WaitResult = incfs::WaitResult; using Features = incfs::Features; using Metrics = incfs::Metrics; using LastReadError = incfs::LastReadError; using ExistingMountCallback = android::base::function_ref< void(std::string_view root, std::string_view backingDir, std::span> binds)>; using FileCallback = android::base::function_ref; static std::string toString(FileId fileId); virtual ~IncFsWrapper() = default; virtual Features features() const = 0; virtual void listExistingMounts(const ExistingMountCallback& cb) const = 0; virtual Control openMount(std::string_view path) const = 0; virtual Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs, IncFsFd blocksWritten) const = 0; virtual ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id, incfs::NewFileParams params) const = 0; virtual ErrorCode makeMappedFile(const Control& control, std::string_view path, int mode, incfs::NewMappedFileParams params) const = 0; virtual ErrorCode makeDir(const Control& control, std::string_view path, int mode) const = 0; virtual ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const = 0; virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0; virtual incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const = 0; virtual FileId getFileId(const Control& control, std::string_view path) const = 0; virtual std::pair countFilledBlocks( const Control& control, std::string_view path) const = 0; virtual incfs::LoadingState isFileFullyLoaded(const Control& control, std::string_view path) const = 0; virtual incfs::LoadingState isFileFullyLoaded(const Control& control, FileId id) const = 0; virtual incfs::LoadingState isEverythingFullyLoaded(const Control& control) const = 0; virtual ErrorCode link(const Control& control, std::string_view from, std::string_view to) const = 0; virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0; virtual UniqueFd openForSpecialOps(const Control& control, FileId id) const = 0; virtual ErrorCode writeBlocks(std::span blocks) const = 0; virtual ErrorCode reserveSpace(const Control& control, FileId id, IncFsSize size) const = 0; virtual WaitResult waitForPendingReads( const Control& control, std::chrono::milliseconds timeout, std::vector* pendingReadsBuffer) const = 0; virtual ErrorCode setUidReadTimeouts( const Control& control, const std::vector<::android::os::incremental::PerUidReadTimeouts>& perUidReadTimeouts) const = 0; virtual ErrorCode forEachFile(const Control& control, FileCallback cb) const = 0; virtual ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const = 0; virtual std::optional getMetrics(std::string_view sysfsName) const = 0; virtual std::optional getLastReadError(const Control& control) const = 0; }; class AppOpsManagerWrapper { public: virtual ~AppOpsManagerWrapper() = default; virtual binder::Status checkPermission(const char* permission, const char* operation, const char* package) const = 0; virtual void startWatchingMode(int32_t op, const String16& packageName, const sp& callback) = 0; virtual void stopWatchingMode(const sp& callback) = 0; }; class JniWrapper { public: virtual ~JniWrapper() = default; virtual void initializeForCurrentThread() const = 0; }; class LooperWrapper { public: virtual ~LooperWrapper() = default; virtual int addFd(int fd, int ident, int events, android::Looper_callbackFunc callback, void* data) = 0; virtual int removeFd(int fd) = 0; virtual void wake() = 0; virtual int pollAll(int timeoutMillis) = 0; }; class TimedQueueWrapper { public: virtual ~TimedQueueWrapper() = default; virtual void addJob(MountId id, Milliseconds after, Job what) = 0; virtual void removeJobs(MountId id) = 0; virtual void stop() = 0; }; class FsWrapper { public: virtual ~FsWrapper() = default; using FileCallback = android::base::function_ref; virtual void listFilesRecursive(std::string_view directoryPath, FileCallback onFile) const = 0; }; class ClockWrapper { public: virtual ~ClockWrapper() = default; virtual TimePoint now() const = 0; }; class ServiceManagerWrapper { public: virtual ~ServiceManagerWrapper() = default; virtual std::unique_ptr getVoldService() = 0; virtual std::unique_ptr getDataLoaderManager() = 0; virtual std::unique_ptr getIncFs() = 0; virtual std::unique_ptr getAppOpsManager() = 0; virtual std::unique_ptr getJni() = 0; virtual std::unique_ptr getLooper() = 0; virtual std::unique_ptr getTimedQueue() = 0; virtual std::unique_ptr getProgressUpdateJobQueue() = 0; virtual std::unique_ptr getFs() = 0; virtual std::unique_ptr getClock() = 0; }; // --- Real stuff --- class RealServiceManager : public ServiceManagerWrapper { public: RealServiceManager(sp serviceManager, JNIEnv* env); ~RealServiceManager() = default; std::unique_ptr getVoldService() final; std::unique_ptr getDataLoaderManager() final; std::unique_ptr getIncFs() final; std::unique_ptr getAppOpsManager() final; std::unique_ptr getJni() final; std::unique_ptr getLooper() final; std::unique_ptr getTimedQueue() final; std::unique_ptr getProgressUpdateJobQueue() final; std::unique_ptr getFs() final; std::unique_ptr getClock() final; private: template sp getRealService(std::string_view serviceName) const; sp mServiceManager; JavaVM* const mJvm; }; } // namespace android::incremental