blob: a76aa625ebc64ead41856035daca422a1d7e5e29 [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
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070017#define LOG_TAG "IncrementalService"
18
Songchun Fan3c82a302019-11-29 14:23:45 -080019#include "ServiceWrappers.h"
20
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070021#include <MountRegistry.h>
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070022#include <android-base/logging.h>
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070023#include <android/content/pm/IDataLoaderManager.h>
24#include <android/os/IVold.h>
25#include <binder/AppOpsManager.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080026#include <utils/String16.h>
27
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070028#include "IncrementalServiceValidation.h"
29
Songchun Fan3c82a302019-11-29 14:23:45 -080030using namespace std::literals;
31
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070032namespace android::incremental {
Songchun Fan3c82a302019-11-29 14:23:45 -080033
34static constexpr auto kVoldServiceName = "vold"sv;
Songchun Fan68645c42020-02-27 15:57:35 -080035static constexpr auto kDataLoaderManagerName = "dataloader_manager"sv;
Songchun Fan3c82a302019-11-29 14:23:45 -080036
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070037class RealVoldService : public VoldServiceWrapper {
38public:
Yurii Zubrytskyi510037b2020-04-22 15:46:21 -070039 RealVoldService(sp<os::IVold> vold) : mInterface(std::move(vold)) {}
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070040 ~RealVoldService() = default;
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070041 binder::Status mountIncFs(
42 const std::string& backingPath, const std::string& targetDir, int32_t flags,
43 os::incremental::IncrementalFileSystemControlParcel* _aidl_return) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070044 return mInterface->mountIncFs(backingPath, targetDir, flags, _aidl_return);
45 }
46 binder::Status unmountIncFs(const std::string& dir) const final {
47 return mInterface->unmountIncFs(dir);
48 }
49 binder::Status bindMount(const std::string& sourceDir,
50 const std::string& targetDir) const final {
51 return mInterface->bindMount(sourceDir, targetDir);
52 }
53 binder::Status setIncFsMountOptions(
54 const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
55 bool enableReadLogs) const final {
56 return mInterface->setIncFsMountOptions(control, enableReadLogs);
57 }
58
59private:
60 sp<os::IVold> mInterface;
61};
62
63class RealDataLoaderManager : public DataLoaderManagerWrapper {
64public:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070065 RealDataLoaderManager(sp<content::pm::IDataLoaderManager> manager)
66 : mInterface(std::move(manager)) {}
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070067 ~RealDataLoaderManager() = default;
Alex Buynytskyyea1390f2020-04-22 16:08:50 -070068 binder::Status bindToDataLoader(MountId mountId,
69 const content::pm::DataLoaderParamsParcel& params,
70 const sp<content::pm::IDataLoaderStatusListener>& listener,
71 bool* _aidl_return) const final {
72 return mInterface->bindToDataLoader(mountId, params, listener, _aidl_return);
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070073 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070074 binder::Status getDataLoader(MountId mountId,
75 sp<content::pm::IDataLoader>* _aidl_return) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070076 return mInterface->getDataLoader(mountId, _aidl_return);
77 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -070078 binder::Status unbindFromDataLoader(MountId mountId) const final {
79 return mInterface->unbindFromDataLoader(mountId);
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070080 }
81
82private:
83 sp<content::pm::IDataLoaderManager> mInterface;
84};
85
86class RealAppOpsManager : public AppOpsManagerWrapper {
87public:
88 ~RealAppOpsManager() = default;
89 binder::Status checkPermission(const char* permission, const char* operation,
90 const char* package) const final {
91 return android::incremental::CheckPermissionForDataDelivery(permission, operation, package);
92 }
93 void startWatchingMode(int32_t op, const String16& packageName,
94 const sp<IAppOpsCallback>& callback) final {
95 mAppOpsManager.startWatchingMode(op, packageName, callback);
96 }
97 void stopWatchingMode(const sp<IAppOpsCallback>& callback) final {
98 mAppOpsManager.stopWatchingMode(callback);
99 }
100
101private:
102 android::AppOpsManager mAppOpsManager;
103};
104
105class RealJniWrapper final : public JniWrapper {
106public:
107 RealJniWrapper(JavaVM* jvm);
108 void initializeForCurrentThread() const final;
109
110 static JavaVM* getJvm(JNIEnv* env);
111
112private:
113 JavaVM* const mJvm;
114};
115
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700116class RealLooperWrapper final : public LooperWrapper {
117public:
118 int addFd(int fd, int ident, int events, android::Looper_callbackFunc callback,
119 void* data) final {
120 return mLooper.addFd(fd, ident, events, callback, data);
121 }
122 int removeFd(int fd) final { return mLooper.removeFd(fd); }
123 void wake() final { return mLooper.wake(); }
124 int pollAll(int timeoutMillis) final { return mLooper.pollAll(timeoutMillis); }
125
126private:
127 struct Looper : public android::Looper {
128 Looper() : android::Looper(/*allowNonCallbacks=*/false) {}
129 ~Looper() {}
130 } mLooper;
131};
132
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700133class RealIncFs : public IncFsWrapper {
134public:
135 RealIncFs() = default;
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700136 ~RealIncFs() final = default;
137 void listExistingMounts(const ExistingMountCallback& cb) const final {
138 for (auto mount : incfs::defaultMountRegistry().copyMounts()) {
139 auto binds = mount.binds(); // span() doesn't like rvalue containers, needs to save it.
140 cb(mount.root(), mount.backingDir(), binds);
141 }
142 }
143 Control openMount(std::string_view path) const final { return incfs::open(path); }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700144 Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const final {
145 return incfs::createControl(cmd, pendingReads, logs);
146 }
147 ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700148 incfs::NewFileParams params) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700149 return incfs::makeFile(control, path, mode, id, params);
150 }
151 ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final {
152 return incfs::makeDir(control, path, mode);
153 }
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700154 ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const final {
155 return incfs::makeDirs(control, path, mode);
156 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700157 incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700158 return incfs::getMetadata(control, fileid);
159 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700160 incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700161 return incfs::getMetadata(control, path);
162 }
163 FileId getFileId(const Control& control, std::string_view path) const final {
164 return incfs::getFileId(control, path);
165 }
166 ErrorCode link(const Control& control, std::string_view from, std::string_view to) const final {
167 return incfs::link(control, from, to);
168 }
169 ErrorCode unlink(const Control& control, std::string_view path) const final {
170 return incfs::unlink(control, path);
171 }
172 base::unique_fd openForSpecialOps(const Control& control, FileId id) const final {
173 return base::unique_fd{incfs::openForSpecialOps(control, id).release()};
174 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700175 ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final {
176 return incfs::writeBlocks({blocks.data(), size_t(blocks.size())});
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700177 }
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700178 WaitResult waitForPendingReads(const Control& control, std::chrono::milliseconds timeout,
179 std::vector<incfs::ReadInfo>* pendingReadsBuffer) const final {
180 return incfs::waitForPendingReads(control, timeout, pendingReadsBuffer);
181 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700182};
183
184RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
185 : mServiceManager(std::move(serviceManager)), mJvm(RealJniWrapper::getJvm(env)) {}
Songchun Fan3c82a302019-11-29 14:23:45 -0800186
187template <class INTERFACE>
188sp<INTERFACE> RealServiceManager::getRealService(std::string_view serviceName) const {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800189 sp<IBinder> binder =
190 mServiceManager->getService(String16(serviceName.data(), serviceName.size()));
191 if (!binder) {
192 return nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800193 }
194 return interface_cast<INTERFACE>(binder);
195}
196
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800197std::unique_ptr<VoldServiceWrapper> RealServiceManager::getVoldService() {
Songchun Fan3c82a302019-11-29 14:23:45 -0800198 sp<os::IVold> vold = RealServiceManager::getRealService<os::IVold>(kVoldServiceName);
199 if (vold != 0) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800200 return std::make_unique<RealVoldService>(vold);
Songchun Fan3c82a302019-11-29 14:23:45 -0800201 }
202 return nullptr;
203}
204
Songchun Fan68645c42020-02-27 15:57:35 -0800205std::unique_ptr<DataLoaderManagerWrapper> RealServiceManager::getDataLoaderManager() {
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700206 sp<content::pm::IDataLoaderManager> manager =
207 RealServiceManager::getRealService<content::pm::IDataLoaderManager>(
208 kDataLoaderManagerName);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800209 if (manager) {
Songchun Fan68645c42020-02-27 15:57:35 -0800210 return std::make_unique<RealDataLoaderManager>(manager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800211 }
212 return nullptr;
213}
214
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800215std::unique_ptr<IncFsWrapper> RealServiceManager::getIncFs() {
216 return std::make_unique<RealIncFs>();
Songchun Fan3c82a302019-11-29 14:23:45 -0800217}
218
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700219std::unique_ptr<AppOpsManagerWrapper> RealServiceManager::getAppOpsManager() {
220 return std::make_unique<RealAppOpsManager>();
221}
222
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700223std::unique_ptr<JniWrapper> RealServiceManager::getJni() {
224 return std::make_unique<RealJniWrapper>(mJvm);
225}
226
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700227std::unique_ptr<LooperWrapper> RealServiceManager::getLooper() {
228 return std::make_unique<RealLooperWrapper>();
229}
230
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700231static JavaVM* getJavaVm(JNIEnv* env) {
232 CHECK(env);
233 JavaVM* jvm = nullptr;
234 env->GetJavaVM(&jvm);
235 CHECK(jvm);
236 return jvm;
237}
238
239static JNIEnv* getJniEnv(JavaVM* vm) {
240 JNIEnv* env;
241 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
242 return nullptr;
243 }
244 return env;
245}
246
247static JNIEnv* getOrAttachJniEnv(JavaVM* jvm) {
248 if (!jvm) {
249 LOG(ERROR) << "No JVM instance";
250 return nullptr;
251 }
252
253 JNIEnv* env = getJniEnv(jvm);
254 if (!env) {
255 int result = jvm->AttachCurrentThread(&env, nullptr);
256 if (result != JNI_OK) {
257 LOG(ERROR) << "JVM thread attach failed: " << result;
258 return nullptr;
259 }
260 struct VmDetacher {
261 VmDetacher(JavaVM* vm) : mVm(vm) {}
262 ~VmDetacher() { mVm->DetachCurrentThread(); }
263
264 private:
265 JavaVM* const mVm;
266 };
267 static thread_local VmDetacher detacher(jvm);
268 }
269
270 return env;
271}
272
273RealJniWrapper::RealJniWrapper(JavaVM* jvm) : mJvm(jvm) {
274 CHECK(!!mJvm) << "JVM is unavailable";
275}
276
277void RealJniWrapper::initializeForCurrentThread() const {
278 (void)getOrAttachJniEnv(mJvm);
279}
280
281JavaVM* RealJniWrapper::getJvm(JNIEnv* env) {
282 return getJavaVm(env);
283}
284
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700285} // namespace android::incremental