1 /*
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 
19 #include <android-base/unique_fd.h>
20 #include <android/content/pm/DataLoaderParamsParcel.h>
21 #include <android/content/pm/FileSystemControlParcel.h>
22 #include <android/content/pm/IDataLoader.h>
23 #include <android/content/pm/IDataLoaderStatusListener.h>
24 #include <binder/IAppOpsCallback.h>
25 #include <binder/IServiceManager.h>
26 #include <binder/Status.h>
27 #include <incfs.h>
28 #include <jni.h>
29 #include <utils/Looper.h>
30 
31 #include <memory>
32 #include <span>
33 #include <string>
34 #include <string_view>
35 
36 namespace android::incremental {
37 
38 using Clock = std::chrono::steady_clock;
39 using TimePoint = std::chrono::time_point<Clock>;
40 using Milliseconds = std::chrono::milliseconds;
41 using Job = std::function<void()>;
42 
43 // --- Wrapper interfaces ---
44 
45 using MountId = int32_t;
46 
47 class VoldServiceWrapper {
48 public:
49     virtual ~VoldServiceWrapper() = default;
50     virtual binder::Status mountIncFs(
51             const std::string& backingPath, const std::string& targetDir, int32_t flags,
52             os::incremental::IncrementalFileSystemControlParcel* result) const = 0;
53     virtual binder::Status unmountIncFs(const std::string& dir) const = 0;
54     virtual binder::Status bindMount(const std::string& sourceDir,
55                                      const std::string& targetDir) const = 0;
56     virtual binder::Status setIncFsMountOptions(
57             const os::incremental::IncrementalFileSystemControlParcel& control,
58             bool enableReadLogs) const = 0;
59 };
60 
61 class DataLoaderManagerWrapper {
62 public:
63     virtual ~DataLoaderManagerWrapper() = default;
64     virtual binder::Status bindToDataLoader(
65             MountId mountId, const content::pm::DataLoaderParamsParcel& params,
66             const sp<content::pm::IDataLoaderStatusListener>& listener, bool* result) const = 0;
67     virtual binder::Status getDataLoader(MountId mountId,
68                                          sp<content::pm::IDataLoader>* result) const = 0;
69     virtual binder::Status unbindFromDataLoader(MountId mountId) const = 0;
70 };
71 
72 class IncFsWrapper {
73 public:
74     using Control = incfs::Control;
75     using FileId = incfs::FileId;
76     using ErrorCode = incfs::ErrorCode;
77     using WaitResult = incfs::WaitResult;
78 
79     using ExistingMountCallback =
80             std::function<void(std::string_view root, std::string_view backingDir,
81                                std::span<std::pair<std::string_view, std::string_view>> binds)>;
82 
83     virtual ~IncFsWrapper() = default;
84     virtual void listExistingMounts(const ExistingMountCallback& cb) const = 0;
85     virtual Control openMount(std::string_view path) const = 0;
86     virtual Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const = 0;
87     virtual ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
88                                incfs::NewFileParams params) const = 0;
89     virtual ErrorCode makeDir(const Control& control, std::string_view path, int mode) const = 0;
90     virtual ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const = 0;
91     virtual incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const = 0;
92     virtual incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const = 0;
93     virtual FileId getFileId(const Control& control, std::string_view path) const = 0;
94     virtual ErrorCode link(const Control& control, std::string_view from,
95                            std::string_view to) const = 0;
96     virtual ErrorCode unlink(const Control& control, std::string_view path) const = 0;
97     virtual base::unique_fd openForSpecialOps(const Control& control, FileId id) const = 0;
98     virtual ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const = 0;
99     virtual WaitResult waitForPendingReads(
100             const Control& control, std::chrono::milliseconds timeout,
101             std::vector<incfs::ReadInfo>* pendingReadsBuffer) const = 0;
102 };
103 
104 class AppOpsManagerWrapper {
105 public:
106     virtual ~AppOpsManagerWrapper() = default;
107     virtual binder::Status checkPermission(const char* permission, const char* operation,
108                                            const char* package) const = 0;
109     virtual void startWatchingMode(int32_t op, const String16& packageName, const sp<IAppOpsCallback>& callback) = 0;
110     virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) = 0;
111 };
112 
113 class JniWrapper {
114 public:
115     virtual ~JniWrapper() = default;
116     virtual void initializeForCurrentThread() const = 0;
117 };
118 
119 class LooperWrapper {
120 public:
121     virtual ~LooperWrapper() = default;
122     virtual int addFd(int fd, int ident, int events, android::Looper_callbackFunc callback,
123                       void* data) = 0;
124     virtual int removeFd(int fd) = 0;
125     virtual void wake() = 0;
126     virtual int pollAll(int timeoutMillis) = 0;
127 };
128 
129 class TimedQueueWrapper {
130 public:
131     virtual ~TimedQueueWrapper() = default;
132     virtual void addJob(MountId id, Milliseconds after, Job what) = 0;
133     virtual void removeJobs(MountId id) = 0;
134     virtual void stop() = 0;
135 };
136 
137 class ServiceManagerWrapper {
138 public:
139     virtual ~ServiceManagerWrapper() = default;
140     virtual std::unique_ptr<VoldServiceWrapper> getVoldService() = 0;
141     virtual std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() = 0;
142     virtual std::unique_ptr<IncFsWrapper> getIncFs() = 0;
143     virtual std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() = 0;
144     virtual std::unique_ptr<JniWrapper> getJni() = 0;
145     virtual std::unique_ptr<LooperWrapper> getLooper() = 0;
146     virtual std::unique_ptr<TimedQueueWrapper> getTimedQueue() = 0;
147 };
148 
149 // --- Real stuff ---
150 
151 class RealServiceManager : public ServiceManagerWrapper {
152 public:
153     RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env);
154     ~RealServiceManager() = default;
155     std::unique_ptr<VoldServiceWrapper> getVoldService() final;
156     std::unique_ptr<DataLoaderManagerWrapper> getDataLoaderManager() final;
157     std::unique_ptr<IncFsWrapper> getIncFs() final;
158     std::unique_ptr<AppOpsManagerWrapper> getAppOpsManager() final;
159     std::unique_ptr<JniWrapper> getJni() final;
160     std::unique_ptr<LooperWrapper> getLooper() final;
161     std::unique_ptr<TimedQueueWrapper> getTimedQueue() final;
162 
163 private:
164     template <class INTERFACE>
165     sp<INTERFACE> getRealService(std::string_view serviceName) const;
166     sp<android::IServiceManager> mServiceManager;
167     JavaVM* const mJvm;
168 };
169 
170 } // namespace android::incremental
171