blob: 99a35adb50744b2f83c1a40aaeac112780cf53e3 [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
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -070028#include <thread>
29
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070030#include "IncrementalServiceValidation.h"
31
Songchun Fan3c82a302019-11-29 14:23:45 -080032using namespace std::literals;
33
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070034namespace android::incremental {
Songchun Fan3c82a302019-11-29 14:23:45 -080035
36static constexpr auto kVoldServiceName = "vold"sv;
Songchun Fan68645c42020-02-27 15:57:35 -080037static constexpr auto kDataLoaderManagerName = "dataloader_manager"sv;
Songchun Fan3c82a302019-11-29 14:23:45 -080038
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070039class RealVoldService : public VoldServiceWrapper {
40public:
Yurii Zubrytskyi510037b2020-04-22 15:46:21 -070041 RealVoldService(sp<os::IVold> vold) : mInterface(std::move(vold)) {}
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070042 ~RealVoldService() = default;
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070043 binder::Status mountIncFs(
44 const std::string& backingPath, const std::string& targetDir, int32_t flags,
45 os::incremental::IncrementalFileSystemControlParcel* _aidl_return) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070046 return mInterface->mountIncFs(backingPath, targetDir, flags, _aidl_return);
47 }
48 binder::Status unmountIncFs(const std::string& dir) const final {
49 return mInterface->unmountIncFs(dir);
50 }
51 binder::Status bindMount(const std::string& sourceDir,
52 const std::string& targetDir) const final {
53 return mInterface->bindMount(sourceDir, targetDir);
54 }
55 binder::Status setIncFsMountOptions(
56 const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
57 bool enableReadLogs) const final {
58 return mInterface->setIncFsMountOptions(control, enableReadLogs);
59 }
60
61private:
62 sp<os::IVold> mInterface;
63};
64
65class RealDataLoaderManager : public DataLoaderManagerWrapper {
66public:
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070067 RealDataLoaderManager(sp<content::pm::IDataLoaderManager> manager)
68 : mInterface(std::move(manager)) {}
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070069 ~RealDataLoaderManager() = default;
Alex Buynytskyyea1390f2020-04-22 16:08:50 -070070 binder::Status bindToDataLoader(MountId mountId,
71 const content::pm::DataLoaderParamsParcel& params,
72 const sp<content::pm::IDataLoaderStatusListener>& listener,
73 bool* _aidl_return) const final {
74 return mInterface->bindToDataLoader(mountId, params, listener, _aidl_return);
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070075 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -070076 binder::Status getDataLoader(MountId mountId,
77 sp<content::pm::IDataLoader>* _aidl_return) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070078 return mInterface->getDataLoader(mountId, _aidl_return);
79 }
Alex Buynytskyyea1390f2020-04-22 16:08:50 -070080 binder::Status unbindFromDataLoader(MountId mountId) const final {
81 return mInterface->unbindFromDataLoader(mountId);
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070082 }
83
84private:
85 sp<content::pm::IDataLoaderManager> mInterface;
86};
87
88class RealAppOpsManager : public AppOpsManagerWrapper {
89public:
90 ~RealAppOpsManager() = default;
91 binder::Status checkPermission(const char* permission, const char* operation,
92 const char* package) const final {
93 return android::incremental::CheckPermissionForDataDelivery(permission, operation, package);
94 }
95 void startWatchingMode(int32_t op, const String16& packageName,
96 const sp<IAppOpsCallback>& callback) final {
97 mAppOpsManager.startWatchingMode(op, packageName, callback);
98 }
99 void stopWatchingMode(const sp<IAppOpsCallback>& callback) final {
100 mAppOpsManager.stopWatchingMode(callback);
101 }
102
103private:
104 android::AppOpsManager mAppOpsManager;
105};
106
107class RealJniWrapper final : public JniWrapper {
108public:
109 RealJniWrapper(JavaVM* jvm);
110 void initializeForCurrentThread() const final;
111
112 static JavaVM* getJvm(JNIEnv* env);
113
114private:
115 JavaVM* const mJvm;
116};
117
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700118class RealLooperWrapper final : public LooperWrapper {
119public:
120 int addFd(int fd, int ident, int events, android::Looper_callbackFunc callback,
121 void* data) final {
122 return mLooper.addFd(fd, ident, events, callback, data);
123 }
124 int removeFd(int fd) final { return mLooper.removeFd(fd); }
125 void wake() final { return mLooper.wake(); }
126 int pollAll(int timeoutMillis) final { return mLooper.pollAll(timeoutMillis); }
127
128private:
129 struct Looper : public android::Looper {
130 Looper() : android::Looper(/*allowNonCallbacks=*/false) {}
131 ~Looper() {}
132 } mLooper;
133};
134
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700135class RealIncFs : public IncFsWrapper {
136public:
137 RealIncFs() = default;
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700138 ~RealIncFs() final = default;
139 void listExistingMounts(const ExistingMountCallback& cb) const final {
140 for (auto mount : incfs::defaultMountRegistry().copyMounts()) {
141 auto binds = mount.binds(); // span() doesn't like rvalue containers, needs to save it.
142 cb(mount.root(), mount.backingDir(), binds);
143 }
144 }
145 Control openMount(std::string_view path) const final { return incfs::open(path); }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700146 Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const final {
147 return incfs::createControl(cmd, pendingReads, logs);
148 }
149 ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700150 incfs::NewFileParams params) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700151 return incfs::makeFile(control, path, mode, id, params);
152 }
153 ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final {
154 return incfs::makeDir(control, path, mode);
155 }
Yurii Zubrytskyiefebb452020-04-22 13:59:06 -0700156 ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const final {
157 return incfs::makeDirs(control, path, mode);
158 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700159 incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700160 return incfs::getMetadata(control, fileid);
161 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700162 incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const final {
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700163 return incfs::getMetadata(control, path);
164 }
165 FileId getFileId(const Control& control, std::string_view path) const final {
166 return incfs::getFileId(control, path);
167 }
168 ErrorCode link(const Control& control, std::string_view from, std::string_view to) const final {
169 return incfs::link(control, from, to);
170 }
171 ErrorCode unlink(const Control& control, std::string_view path) const final {
172 return incfs::unlink(control, path);
173 }
174 base::unique_fd openForSpecialOps(const Control& control, FileId id) const final {
175 return base::unique_fd{incfs::openForSpecialOps(control, id).release()};
176 }
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700177 ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final {
178 return incfs::writeBlocks({blocks.data(), size_t(blocks.size())});
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700179 }
Alex Buynytskyy8ef61ae2020-05-08 16:18:52 -0700180 WaitResult waitForPendingReads(const Control& control, std::chrono::milliseconds timeout,
181 std::vector<incfs::ReadInfo>* pendingReadsBuffer) const final {
182 return incfs::waitForPendingReads(control, timeout, pendingReadsBuffer);
183 }
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700184};
185
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700186static JNIEnv* getOrAttachJniEnv(JavaVM* jvm);
187
188class RealTimedQueueWrapper : public TimedQueueWrapper {
189public:
190 RealTimedQueueWrapper(JavaVM* jvm) {
191 mThread = std::thread([this, jvm]() {
192 (void)getOrAttachJniEnv(jvm);
193 runTimers();
194 });
195 }
196 ~RealTimedQueueWrapper() final {
197 CHECK(!mRunning) << "call stop first";
198 CHECK(!mThread.joinable()) << "call stop first";
199 }
200
201 void addJob(MountId id, Milliseconds after, Job what) final {
202 const auto now = Clock::now();
203 {
204 std::unique_lock lock(mMutex);
205 mJobs.insert(TimedJob{id, now + after, std::move(what)});
206 }
207 mCondition.notify_all();
208 }
209 void removeJobs(MountId id) final {
210 std::unique_lock lock(mMutex);
211 std::erase_if(mJobs, [id](auto&& item) { return item.id == id; });
212 }
213 void stop() final {
214 {
215 std::unique_lock lock(mMutex);
216 mRunning = false;
217 }
218 mCondition.notify_all();
219 mThread.join();
220 mJobs.clear();
221 }
222
223private:
224 void runTimers() {
225 static constexpr TimePoint kInfinityTs{Clock::duration::max()};
226 TimePoint nextJobTs = kInfinityTs;
227 std::unique_lock lock(mMutex);
228 for (;;) {
229 mCondition.wait_until(lock, nextJobTs, [this, nextJobTs]() {
230 const auto now = Clock::now();
231 const auto firstJobTs = !mJobs.empty() ? mJobs.begin()->when : kInfinityTs;
232 return !mRunning || firstJobTs <= now || firstJobTs < nextJobTs;
233 });
234 if (!mRunning) {
235 return;
236 }
237
238 const auto now = Clock::now();
239 auto it = mJobs.begin();
240 // Always acquire begin(). We can't use it after unlock as mTimedJobs can change.
241 for (; it != mJobs.end() && it->when <= now; it = mJobs.begin()) {
242 auto job = std::move(it->what);
243 mJobs.erase(it);
244
245 lock.unlock();
246 job();
247 lock.lock();
248 }
249 nextJobTs = it != mJobs.end() ? it->when : kInfinityTs;
250 }
251 }
252
253 struct TimedJob {
254 MountId id;
255 TimePoint when;
256 Job what;
257 friend bool operator<(const TimedJob& lhs, const TimedJob& rhs) {
258 return lhs.when < rhs.when;
259 }
260 };
261 bool mRunning = true;
262 std::set<TimedJob> mJobs;
263 std::condition_variable mCondition;
264 std::mutex mMutex;
265 std::thread mThread;
266};
267
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700268RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
269 : mServiceManager(std::move(serviceManager)), mJvm(RealJniWrapper::getJvm(env)) {}
Songchun Fan3c82a302019-11-29 14:23:45 -0800270
271template <class INTERFACE>
272sp<INTERFACE> RealServiceManager::getRealService(std::string_view serviceName) const {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800273 sp<IBinder> binder =
274 mServiceManager->getService(String16(serviceName.data(), serviceName.size()));
275 if (!binder) {
276 return nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800277 }
278 return interface_cast<INTERFACE>(binder);
279}
280
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800281std::unique_ptr<VoldServiceWrapper> RealServiceManager::getVoldService() {
Songchun Fan3c82a302019-11-29 14:23:45 -0800282 sp<os::IVold> vold = RealServiceManager::getRealService<os::IVold>(kVoldServiceName);
283 if (vold != 0) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800284 return std::make_unique<RealVoldService>(vold);
Songchun Fan3c82a302019-11-29 14:23:45 -0800285 }
286 return nullptr;
287}
288
Songchun Fan68645c42020-02-27 15:57:35 -0800289std::unique_ptr<DataLoaderManagerWrapper> RealServiceManager::getDataLoaderManager() {
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700290 sp<content::pm::IDataLoaderManager> manager =
291 RealServiceManager::getRealService<content::pm::IDataLoaderManager>(
292 kDataLoaderManagerName);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800293 if (manager) {
Songchun Fan68645c42020-02-27 15:57:35 -0800294 return std::make_unique<RealDataLoaderManager>(manager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800295 }
296 return nullptr;
297}
298
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800299std::unique_ptr<IncFsWrapper> RealServiceManager::getIncFs() {
300 return std::make_unique<RealIncFs>();
Songchun Fan3c82a302019-11-29 14:23:45 -0800301}
302
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700303std::unique_ptr<AppOpsManagerWrapper> RealServiceManager::getAppOpsManager() {
304 return std::make_unique<RealAppOpsManager>();
305}
306
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700307std::unique_ptr<JniWrapper> RealServiceManager::getJni() {
308 return std::make_unique<RealJniWrapper>(mJvm);
309}
310
Alex Buynytskyycca2c112020-05-05 12:48:41 -0700311std::unique_ptr<LooperWrapper> RealServiceManager::getLooper() {
312 return std::make_unique<RealLooperWrapper>();
313}
314
Alex Buynytskyy46d3ddb2020-05-29 12:05:05 -0700315std::unique_ptr<TimedQueueWrapper> RealServiceManager::getTimedQueue() {
316 return std::make_unique<RealTimedQueueWrapper>(mJvm);
317}
318
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700319static JavaVM* getJavaVm(JNIEnv* env) {
320 CHECK(env);
321 JavaVM* jvm = nullptr;
322 env->GetJavaVM(&jvm);
323 CHECK(jvm);
324 return jvm;
325}
326
327static JNIEnv* getJniEnv(JavaVM* vm) {
328 JNIEnv* env;
329 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
330 return nullptr;
331 }
332 return env;
333}
334
335static JNIEnv* getOrAttachJniEnv(JavaVM* jvm) {
336 if (!jvm) {
337 LOG(ERROR) << "No JVM instance";
338 return nullptr;
339 }
340
341 JNIEnv* env = getJniEnv(jvm);
342 if (!env) {
343 int result = jvm->AttachCurrentThread(&env, nullptr);
344 if (result != JNI_OK) {
345 LOG(ERROR) << "JVM thread attach failed: " << result;
346 return nullptr;
347 }
348 struct VmDetacher {
349 VmDetacher(JavaVM* vm) : mVm(vm) {}
350 ~VmDetacher() { mVm->DetachCurrentThread(); }
351
352 private:
353 JavaVM* const mVm;
354 };
355 static thread_local VmDetacher detacher(jvm);
356 }
357
358 return env;
359}
360
361RealJniWrapper::RealJniWrapper(JavaVM* jvm) : mJvm(jvm) {
362 CHECK(!!mJvm) << "JVM is unavailable";
363}
364
365void RealJniWrapper::initializeForCurrentThread() const {
366 (void)getOrAttachJniEnv(mJvm);
367}
368
369JavaVM* RealJniWrapper::getJvm(JNIEnv* env) {
370 return getJavaVm(env);
371}
372
Yurii Zubrytskyi629051fd2020-04-17 23:13:47 -0700373} // namespace android::incremental