xref: /aosp_15_r20/frameworks/base/services/incremental/ServiceWrappers.cpp (revision d57664e9bc4670b3ecf6748a746a57c557b6bc9e)
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 #define LOG_TAG "IncrementalService"
18*d57664e9SAndroid Build Coastguard Worker 
19*d57664e9SAndroid Build Coastguard Worker #include "ServiceWrappers.h"
20*d57664e9SAndroid Build Coastguard Worker 
21*d57664e9SAndroid Build Coastguard Worker #include <MountRegistry.h>
22*d57664e9SAndroid Build Coastguard Worker #include <android-base/logging.h>
23*d57664e9SAndroid Build Coastguard Worker #include <android/content/pm/IDataLoaderManager.h>
24*d57664e9SAndroid Build Coastguard Worker #include <android/os/IVold.h>
25*d57664e9SAndroid Build Coastguard Worker #include <binder/AppOpsManager.h>
26*d57664e9SAndroid Build Coastguard Worker #include <utils/String16.h>
27*d57664e9SAndroid Build Coastguard Worker 
28*d57664e9SAndroid Build Coastguard Worker #include <filesystem>
29*d57664e9SAndroid Build Coastguard Worker #include <thread>
30*d57664e9SAndroid Build Coastguard Worker 
31*d57664e9SAndroid Build Coastguard Worker #include "IncrementalServiceValidation.h"
32*d57664e9SAndroid Build Coastguard Worker 
33*d57664e9SAndroid Build Coastguard Worker using namespace std::literals;
34*d57664e9SAndroid Build Coastguard Worker 
35*d57664e9SAndroid Build Coastguard Worker namespace android::incremental {
36*d57664e9SAndroid Build Coastguard Worker 
37*d57664e9SAndroid Build Coastguard Worker static constexpr auto kVoldServiceName = "vold"sv;
38*d57664e9SAndroid Build Coastguard Worker static constexpr auto kDataLoaderManagerName = "dataloader_manager"sv;
39*d57664e9SAndroid Build Coastguard Worker 
40*d57664e9SAndroid Build Coastguard Worker class RealVoldService : public VoldServiceWrapper {
41*d57664e9SAndroid Build Coastguard Worker public:
RealVoldService(sp<os::IVold> vold)42*d57664e9SAndroid Build Coastguard Worker     RealVoldService(sp<os::IVold> vold) : mInterface(std::move(vold)) {}
43*d57664e9SAndroid Build Coastguard Worker     ~RealVoldService() = default;
mountIncFs(const std::string & backingPath,const std::string & targetDir,int32_t flags,const std::string & sysfsName,os::incremental::IncrementalFileSystemControlParcel * _aidl_return) const44*d57664e9SAndroid Build Coastguard Worker     binder::Status mountIncFs(
45*d57664e9SAndroid Build Coastguard Worker             const std::string& backingPath, const std::string& targetDir, int32_t flags,
46*d57664e9SAndroid Build Coastguard Worker             const std::string& sysfsName,
47*d57664e9SAndroid Build Coastguard Worker             os::incremental::IncrementalFileSystemControlParcel* _aidl_return) const final {
48*d57664e9SAndroid Build Coastguard Worker         return mInterface->mountIncFs(backingPath, targetDir, flags, sysfsName, _aidl_return);
49*d57664e9SAndroid Build Coastguard Worker     }
unmountIncFs(const std::string & dir) const50*d57664e9SAndroid Build Coastguard Worker     binder::Status unmountIncFs(const std::string& dir) const final {
51*d57664e9SAndroid Build Coastguard Worker         return mInterface->unmountIncFs(dir);
52*d57664e9SAndroid Build Coastguard Worker     }
bindMount(const std::string & sourceDir,const std::string & targetDir) const53*d57664e9SAndroid Build Coastguard Worker     binder::Status bindMount(const std::string& sourceDir,
54*d57664e9SAndroid Build Coastguard Worker                              const std::string& targetDir) const final {
55*d57664e9SAndroid Build Coastguard Worker         return mInterface->bindMount(sourceDir, targetDir);
56*d57664e9SAndroid Build Coastguard Worker     }
setIncFsMountOptions(const::android::os::incremental::IncrementalFileSystemControlParcel & control,bool enableReadLogs,bool enableReadTimeouts,const std::string & sysfsName) const57*d57664e9SAndroid Build Coastguard Worker     binder::Status setIncFsMountOptions(
58*d57664e9SAndroid Build Coastguard Worker             const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
59*d57664e9SAndroid Build Coastguard Worker             bool enableReadLogs, bool enableReadTimeouts,
60*d57664e9SAndroid Build Coastguard Worker             const std::string& sysfsName) const final {
61*d57664e9SAndroid Build Coastguard Worker         return mInterface->setIncFsMountOptions(control, enableReadLogs, enableReadTimeouts,
62*d57664e9SAndroid Build Coastguard Worker                                                 sysfsName);
63*d57664e9SAndroid Build Coastguard Worker     }
64*d57664e9SAndroid Build Coastguard Worker 
65*d57664e9SAndroid Build Coastguard Worker private:
66*d57664e9SAndroid Build Coastguard Worker     sp<os::IVold> mInterface;
67*d57664e9SAndroid Build Coastguard Worker };
68*d57664e9SAndroid Build Coastguard Worker 
69*d57664e9SAndroid Build Coastguard Worker class RealDataLoaderManager : public DataLoaderManagerWrapper {
70*d57664e9SAndroid Build Coastguard Worker public:
RealDataLoaderManager(sp<content::pm::IDataLoaderManager> manager)71*d57664e9SAndroid Build Coastguard Worker     RealDataLoaderManager(sp<content::pm::IDataLoaderManager> manager)
72*d57664e9SAndroid Build Coastguard Worker           : mInterface(std::move(manager)) {}
73*d57664e9SAndroid Build Coastguard Worker     ~RealDataLoaderManager() = default;
bindToDataLoader(MountId mountId,const content::pm::DataLoaderParamsParcel & params,int bindDelayMs,const sp<content::pm::IDataLoaderStatusListener> & listener,bool * _aidl_return) const74*d57664e9SAndroid Build Coastguard Worker     binder::Status bindToDataLoader(MountId mountId,
75*d57664e9SAndroid Build Coastguard Worker                                     const content::pm::DataLoaderParamsParcel& params,
76*d57664e9SAndroid Build Coastguard Worker                                     int bindDelayMs,
77*d57664e9SAndroid Build Coastguard Worker                                     const sp<content::pm::IDataLoaderStatusListener>& listener,
78*d57664e9SAndroid Build Coastguard Worker                                     bool* _aidl_return) const final {
79*d57664e9SAndroid Build Coastguard Worker         return mInterface->bindToDataLoader(mountId, params, bindDelayMs, listener, _aidl_return);
80*d57664e9SAndroid Build Coastguard Worker     }
getDataLoader(MountId mountId,sp<content::pm::IDataLoader> * _aidl_return) const81*d57664e9SAndroid Build Coastguard Worker     binder::Status getDataLoader(MountId mountId,
82*d57664e9SAndroid Build Coastguard Worker                                  sp<content::pm::IDataLoader>* _aidl_return) const final {
83*d57664e9SAndroid Build Coastguard Worker         return mInterface->getDataLoader(mountId, _aidl_return);
84*d57664e9SAndroid Build Coastguard Worker     }
unbindFromDataLoader(MountId mountId) const85*d57664e9SAndroid Build Coastguard Worker     binder::Status unbindFromDataLoader(MountId mountId) const final {
86*d57664e9SAndroid Build Coastguard Worker         return mInterface->unbindFromDataLoader(mountId);
87*d57664e9SAndroid Build Coastguard Worker     }
88*d57664e9SAndroid Build Coastguard Worker 
89*d57664e9SAndroid Build Coastguard Worker private:
90*d57664e9SAndroid Build Coastguard Worker     sp<content::pm::IDataLoaderManager> mInterface;
91*d57664e9SAndroid Build Coastguard Worker };
92*d57664e9SAndroid Build Coastguard Worker 
93*d57664e9SAndroid Build Coastguard Worker class RealAppOpsManager : public AppOpsManagerWrapper {
94*d57664e9SAndroid Build Coastguard Worker public:
95*d57664e9SAndroid Build Coastguard Worker     ~RealAppOpsManager() = default;
checkPermission(const char * permission,const char * operation,const char * package) const96*d57664e9SAndroid Build Coastguard Worker     binder::Status checkPermission(const char* permission, const char* operation,
97*d57664e9SAndroid Build Coastguard Worker                                    const char* package) const final {
98*d57664e9SAndroid Build Coastguard Worker         return android::incremental::CheckPermissionForDataDelivery(permission, operation, package);
99*d57664e9SAndroid Build Coastguard Worker     }
startWatchingMode(int32_t op,const String16 & packageName,const sp<IAppOpsCallback> & callback)100*d57664e9SAndroid Build Coastguard Worker     void startWatchingMode(int32_t op, const String16& packageName,
101*d57664e9SAndroid Build Coastguard Worker                            const sp<IAppOpsCallback>& callback) final {
102*d57664e9SAndroid Build Coastguard Worker         mAppOpsManager.startWatchingMode(op, packageName, callback);
103*d57664e9SAndroid Build Coastguard Worker     }
stopWatchingMode(const sp<IAppOpsCallback> & callback)104*d57664e9SAndroid Build Coastguard Worker     void stopWatchingMode(const sp<IAppOpsCallback>& callback) final {
105*d57664e9SAndroid Build Coastguard Worker         mAppOpsManager.stopWatchingMode(callback);
106*d57664e9SAndroid Build Coastguard Worker     }
107*d57664e9SAndroid Build Coastguard Worker 
108*d57664e9SAndroid Build Coastguard Worker private:
109*d57664e9SAndroid Build Coastguard Worker     android::AppOpsManager mAppOpsManager;
110*d57664e9SAndroid Build Coastguard Worker };
111*d57664e9SAndroid Build Coastguard Worker 
112*d57664e9SAndroid Build Coastguard Worker class RealJniWrapper final : public JniWrapper {
113*d57664e9SAndroid Build Coastguard Worker public:
114*d57664e9SAndroid Build Coastguard Worker     RealJniWrapper(JavaVM* jvm);
115*d57664e9SAndroid Build Coastguard Worker     void initializeForCurrentThread() const final;
116*d57664e9SAndroid Build Coastguard Worker 
117*d57664e9SAndroid Build Coastguard Worker     static JavaVM* getJvm(JNIEnv* env);
118*d57664e9SAndroid Build Coastguard Worker 
119*d57664e9SAndroid Build Coastguard Worker private:
120*d57664e9SAndroid Build Coastguard Worker     JavaVM* const mJvm;
121*d57664e9SAndroid Build Coastguard Worker };
122*d57664e9SAndroid Build Coastguard Worker 
123*d57664e9SAndroid Build Coastguard Worker class RealLooperWrapper final : public LooperWrapper {
124*d57664e9SAndroid Build Coastguard Worker public:
addFd(int fd,int ident,int events,android::Looper_callbackFunc callback,void * data)125*d57664e9SAndroid Build Coastguard Worker     int addFd(int fd, int ident, int events, android::Looper_callbackFunc callback,
126*d57664e9SAndroid Build Coastguard Worker               void* data) final {
127*d57664e9SAndroid Build Coastguard Worker         return mLooper.addFd(fd, ident, events, callback, data);
128*d57664e9SAndroid Build Coastguard Worker     }
removeFd(int fd)129*d57664e9SAndroid Build Coastguard Worker     int removeFd(int fd) final { return mLooper.removeFd(fd); }
wake()130*d57664e9SAndroid Build Coastguard Worker     void wake() final { return mLooper.wake(); }
pollAll(int timeoutMillis)131*d57664e9SAndroid Build Coastguard Worker     int pollAll(int timeoutMillis) final { return mLooper.pollAll(timeoutMillis); }
132*d57664e9SAndroid Build Coastguard Worker 
133*d57664e9SAndroid Build Coastguard Worker private:
134*d57664e9SAndroid Build Coastguard Worker     struct Looper : public android::Looper {
Looperandroid::incremental::RealLooperWrapper::Looper135*d57664e9SAndroid Build Coastguard Worker         Looper() : android::Looper(/*allowNonCallbacks=*/false) {}
~Looperandroid::incremental::RealLooperWrapper::Looper136*d57664e9SAndroid Build Coastguard Worker         ~Looper() {}
137*d57664e9SAndroid Build Coastguard Worker     } mLooper;
138*d57664e9SAndroid Build Coastguard Worker };
139*d57664e9SAndroid Build Coastguard Worker 
toString(FileId fileId)140*d57664e9SAndroid Build Coastguard Worker std::string IncFsWrapper::toString(FileId fileId) {
141*d57664e9SAndroid Build Coastguard Worker     return incfs::toString(fileId);
142*d57664e9SAndroid Build Coastguard Worker }
143*d57664e9SAndroid Build Coastguard Worker 
144*d57664e9SAndroid Build Coastguard Worker class RealIncFs final : public IncFsWrapper {
145*d57664e9SAndroid Build Coastguard Worker public:
146*d57664e9SAndroid Build Coastguard Worker     RealIncFs() = default;
147*d57664e9SAndroid Build Coastguard Worker     ~RealIncFs() final = default;
features() const148*d57664e9SAndroid Build Coastguard Worker     Features features() const final { return incfs::features(); }
listExistingMounts(const ExistingMountCallback & cb) const149*d57664e9SAndroid Build Coastguard Worker     void listExistingMounts(const ExistingMountCallback& cb) const final {
150*d57664e9SAndroid Build Coastguard Worker         for (auto mount : incfs::defaultMountRegistry().copyMounts()) {
151*d57664e9SAndroid Build Coastguard Worker             auto binds = mount.binds(); // span() doesn't like rvalue containers, needs to save it.
152*d57664e9SAndroid Build Coastguard Worker             cb(mount.root(), mount.backingDir(), binds);
153*d57664e9SAndroid Build Coastguard Worker         }
154*d57664e9SAndroid Build Coastguard Worker     }
openMount(std::string_view path) const155*d57664e9SAndroid Build Coastguard Worker     Control openMount(std::string_view path) const final { return incfs::open(path); }
createControl(IncFsFd cmd,IncFsFd pendingReads,IncFsFd logs,IncFsFd blocksWritten) const156*d57664e9SAndroid Build Coastguard Worker     Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs,
157*d57664e9SAndroid Build Coastguard Worker                           IncFsFd blocksWritten) const final {
158*d57664e9SAndroid Build Coastguard Worker         return incfs::createControl(cmd, pendingReads, logs, blocksWritten);
159*d57664e9SAndroid Build Coastguard Worker     }
makeFile(const Control & control,std::string_view path,int mode,FileId id,incfs::NewFileParams params) const160*d57664e9SAndroid Build Coastguard Worker     ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
161*d57664e9SAndroid Build Coastguard Worker                        incfs::NewFileParams params) const final {
162*d57664e9SAndroid Build Coastguard Worker         return incfs::makeFile(control, path, mode, id, params);
163*d57664e9SAndroid Build Coastguard Worker     }
makeMappedFile(const Control & control,std::string_view path,int mode,incfs::NewMappedFileParams params) const164*d57664e9SAndroid Build Coastguard Worker     ErrorCode makeMappedFile(const Control& control, std::string_view path, int mode,
165*d57664e9SAndroid Build Coastguard Worker                              incfs::NewMappedFileParams params) const final {
166*d57664e9SAndroid Build Coastguard Worker         return incfs::makeMappedFile(control, path, mode, params);
167*d57664e9SAndroid Build Coastguard Worker     }
makeDir(const Control & control,std::string_view path,int mode) const168*d57664e9SAndroid Build Coastguard Worker     ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final {
169*d57664e9SAndroid Build Coastguard Worker         return incfs::makeDir(control, path, mode);
170*d57664e9SAndroid Build Coastguard Worker     }
makeDirs(const Control & control,std::string_view path,int mode) const171*d57664e9SAndroid Build Coastguard Worker     ErrorCode makeDirs(const Control& control, std::string_view path, int mode) const final {
172*d57664e9SAndroid Build Coastguard Worker         return incfs::makeDirs(control, path, mode);
173*d57664e9SAndroid Build Coastguard Worker     }
getMetadata(const Control & control,FileId fileid) const174*d57664e9SAndroid Build Coastguard Worker     incfs::RawMetadata getMetadata(const Control& control, FileId fileid) const final {
175*d57664e9SAndroid Build Coastguard Worker         return incfs::getMetadata(control, fileid);
176*d57664e9SAndroid Build Coastguard Worker     }
getMetadata(const Control & control,std::string_view path) const177*d57664e9SAndroid Build Coastguard Worker     incfs::RawMetadata getMetadata(const Control& control, std::string_view path) const final {
178*d57664e9SAndroid Build Coastguard Worker         return incfs::getMetadata(control, path);
179*d57664e9SAndroid Build Coastguard Worker     }
getFileId(const Control & control,std::string_view path) const180*d57664e9SAndroid Build Coastguard Worker     FileId getFileId(const Control& control, std::string_view path) const final {
181*d57664e9SAndroid Build Coastguard Worker         return incfs::getFileId(control, path);
182*d57664e9SAndroid Build Coastguard Worker     }
countFilledBlocks(const Control & control,std::string_view path) const183*d57664e9SAndroid Build Coastguard Worker     std::pair<IncFsBlockIndex, IncFsBlockIndex> countFilledBlocks(
184*d57664e9SAndroid Build Coastguard Worker             const Control& control, std::string_view path) const final {
185*d57664e9SAndroid Build Coastguard Worker         if (incfs::features() & Features::v2) {
186*d57664e9SAndroid Build Coastguard Worker             const auto counts = incfs::getBlockCount(control, path);
187*d57664e9SAndroid Build Coastguard Worker             if (!counts) {
188*d57664e9SAndroid Build Coastguard Worker                 return {-errno, -errno};
189*d57664e9SAndroid Build Coastguard Worker             }
190*d57664e9SAndroid Build Coastguard Worker             return {counts->filledDataBlocks + counts->filledHashBlocks,
191*d57664e9SAndroid Build Coastguard Worker                     counts->totalDataBlocks + counts->totalHashBlocks};
192*d57664e9SAndroid Build Coastguard Worker         }
193*d57664e9SAndroid Build Coastguard Worker         const auto fileId = incfs::getFileId(control, path);
194*d57664e9SAndroid Build Coastguard Worker         const auto fd = incfs::openForSpecialOps(control, fileId);
195*d57664e9SAndroid Build Coastguard Worker         int res = fd.get();
196*d57664e9SAndroid Build Coastguard Worker         if (!fd.ok()) {
197*d57664e9SAndroid Build Coastguard Worker             return {res, res};
198*d57664e9SAndroid Build Coastguard Worker         }
199*d57664e9SAndroid Build Coastguard Worker         const auto ranges = incfs::getFilledRanges(res);
200*d57664e9SAndroid Build Coastguard Worker         res = ranges.first;
201*d57664e9SAndroid Build Coastguard Worker         if (res) {
202*d57664e9SAndroid Build Coastguard Worker             return {res, res};
203*d57664e9SAndroid Build Coastguard Worker         }
204*d57664e9SAndroid Build Coastguard Worker         const auto totalBlocksCount = ranges.second.internalRawRanges().endIndex;
205*d57664e9SAndroid Build Coastguard Worker         int filledBlockCount = 0;
206*d57664e9SAndroid Build Coastguard Worker         for (const auto& dataRange : ranges.second.dataRanges()) {
207*d57664e9SAndroid Build Coastguard Worker             filledBlockCount += dataRange.size();
208*d57664e9SAndroid Build Coastguard Worker         }
209*d57664e9SAndroid Build Coastguard Worker         for (const auto& hashRange : ranges.second.hashRanges()) {
210*d57664e9SAndroid Build Coastguard Worker             filledBlockCount += hashRange.size();
211*d57664e9SAndroid Build Coastguard Worker         }
212*d57664e9SAndroid Build Coastguard Worker         return {filledBlockCount, totalBlocksCount};
213*d57664e9SAndroid Build Coastguard Worker     }
isFileFullyLoaded(const Control & control,std::string_view path) const214*d57664e9SAndroid Build Coastguard Worker     incfs::LoadingState isFileFullyLoaded(const Control& control,
215*d57664e9SAndroid Build Coastguard Worker                                           std::string_view path) const final {
216*d57664e9SAndroid Build Coastguard Worker         return incfs::isFullyLoaded(control, path);
217*d57664e9SAndroid Build Coastguard Worker     }
isFileFullyLoaded(const Control & control,FileId id) const218*d57664e9SAndroid Build Coastguard Worker     incfs::LoadingState isFileFullyLoaded(const Control& control, FileId id) const final {
219*d57664e9SAndroid Build Coastguard Worker         return incfs::isFullyLoaded(control, id);
220*d57664e9SAndroid Build Coastguard Worker     }
isEverythingFullyLoaded(const Control & control) const221*d57664e9SAndroid Build Coastguard Worker     incfs::LoadingState isEverythingFullyLoaded(const Control& control) const final {
222*d57664e9SAndroid Build Coastguard Worker         return incfs::isEverythingFullyLoaded(control);
223*d57664e9SAndroid Build Coastguard Worker     }
link(const Control & control,std::string_view from,std::string_view to) const224*d57664e9SAndroid Build Coastguard Worker     ErrorCode link(const Control& control, std::string_view from, std::string_view to) const final {
225*d57664e9SAndroid Build Coastguard Worker         return incfs::link(control, from, to);
226*d57664e9SAndroid Build Coastguard Worker     }
unlink(const Control & control,std::string_view path) const227*d57664e9SAndroid Build Coastguard Worker     ErrorCode unlink(const Control& control, std::string_view path) const final {
228*d57664e9SAndroid Build Coastguard Worker         return incfs::unlink(control, path);
229*d57664e9SAndroid Build Coastguard Worker     }
openForSpecialOps(const Control & control,FileId id) const230*d57664e9SAndroid Build Coastguard Worker     incfs::UniqueFd openForSpecialOps(const Control& control, FileId id) const final {
231*d57664e9SAndroid Build Coastguard Worker         return incfs::openForSpecialOps(control, id);
232*d57664e9SAndroid Build Coastguard Worker     }
writeBlocks(std::span<const incfs::DataBlock> blocks) const233*d57664e9SAndroid Build Coastguard Worker     ErrorCode writeBlocks(std::span<const incfs::DataBlock> blocks) const final {
234*d57664e9SAndroid Build Coastguard Worker         return incfs::writeBlocks({blocks.data(), size_t(blocks.size())});
235*d57664e9SAndroid Build Coastguard Worker     }
reserveSpace(const Control & control,FileId id,IncFsSize size) const236*d57664e9SAndroid Build Coastguard Worker     ErrorCode reserveSpace(const Control& control, FileId id, IncFsSize size) const final {
237*d57664e9SAndroid Build Coastguard Worker         return incfs::reserveSpace(control, id, size);
238*d57664e9SAndroid Build Coastguard Worker     }
waitForPendingReads(const Control & control,std::chrono::milliseconds timeout,std::vector<incfs::ReadInfoWithUid> * pendingReadsBuffer) const239*d57664e9SAndroid Build Coastguard Worker     WaitResult waitForPendingReads(
240*d57664e9SAndroid Build Coastguard Worker             const Control& control, std::chrono::milliseconds timeout,
241*d57664e9SAndroid Build Coastguard Worker             std::vector<incfs::ReadInfoWithUid>* pendingReadsBuffer) const final {
242*d57664e9SAndroid Build Coastguard Worker         return incfs::waitForPendingReads(control, timeout, pendingReadsBuffer);
243*d57664e9SAndroid Build Coastguard Worker     }
setUidReadTimeouts(const Control & control,const std::vector<android::os::incremental::PerUidReadTimeouts> & perUidReadTimeouts) const244*d57664e9SAndroid Build Coastguard Worker     ErrorCode setUidReadTimeouts(const Control& control,
245*d57664e9SAndroid Build Coastguard Worker                                  const std::vector<android::os::incremental::PerUidReadTimeouts>&
246*d57664e9SAndroid Build Coastguard Worker                                          perUidReadTimeouts) const final {
247*d57664e9SAndroid Build Coastguard Worker         std::vector<incfs::UidReadTimeouts> timeouts(perUidReadTimeouts.size());
248*d57664e9SAndroid Build Coastguard Worker         for (int i = 0, size = perUidReadTimeouts.size(); i < size; ++i) {
249*d57664e9SAndroid Build Coastguard Worker             auto& timeout = timeouts[i];
250*d57664e9SAndroid Build Coastguard Worker             const auto& perUidTimeout = perUidReadTimeouts[i];
251*d57664e9SAndroid Build Coastguard Worker             timeout.uid = perUidTimeout.uid;
252*d57664e9SAndroid Build Coastguard Worker             timeout.minTimeUs = perUidTimeout.minTimeUs;
253*d57664e9SAndroid Build Coastguard Worker             timeout.minPendingTimeUs = perUidTimeout.minPendingTimeUs;
254*d57664e9SAndroid Build Coastguard Worker             timeout.maxPendingTimeUs = perUidTimeout.maxPendingTimeUs;
255*d57664e9SAndroid Build Coastguard Worker         }
256*d57664e9SAndroid Build Coastguard Worker         return incfs::setUidReadTimeouts(control, timeouts);
257*d57664e9SAndroid Build Coastguard Worker     }
forEachFile(const Control & control,FileCallback cb) const258*d57664e9SAndroid Build Coastguard Worker     ErrorCode forEachFile(const Control& control, FileCallback cb) const final {
259*d57664e9SAndroid Build Coastguard Worker         return incfs::forEachFile(control,
260*d57664e9SAndroid Build Coastguard Worker                                   [&](auto& control, FileId id) { return cb(control, id); });
261*d57664e9SAndroid Build Coastguard Worker     }
forEachIncompleteFile(const Control & control,FileCallback cb) const262*d57664e9SAndroid Build Coastguard Worker     ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const final {
263*d57664e9SAndroid Build Coastguard Worker         return incfs::forEachIncompleteFile(control, [&](auto& control, FileId id) {
264*d57664e9SAndroid Build Coastguard Worker             return cb(control, id);
265*d57664e9SAndroid Build Coastguard Worker         });
266*d57664e9SAndroid Build Coastguard Worker     }
getMetrics(std::string_view sysfsName) const267*d57664e9SAndroid Build Coastguard Worker     std::optional<Metrics> getMetrics(std::string_view sysfsName) const final {
268*d57664e9SAndroid Build Coastguard Worker         return incfs::getMetrics(sysfsName);
269*d57664e9SAndroid Build Coastguard Worker     }
getLastReadError(const Control & control) const270*d57664e9SAndroid Build Coastguard Worker     std::optional<LastReadError> getLastReadError(const Control& control) const final {
271*d57664e9SAndroid Build Coastguard Worker         return incfs::getLastReadError(control);
272*d57664e9SAndroid Build Coastguard Worker     }
273*d57664e9SAndroid Build Coastguard Worker };
274*d57664e9SAndroid Build Coastguard Worker 
275*d57664e9SAndroid Build Coastguard Worker static JNIEnv* getOrAttachJniEnv(JavaVM* jvm);
276*d57664e9SAndroid Build Coastguard Worker 
277*d57664e9SAndroid Build Coastguard Worker class RealTimedQueueWrapper final : public TimedQueueWrapper {
278*d57664e9SAndroid Build Coastguard Worker public:
RealTimedQueueWrapper(JavaVM * jvm)279*d57664e9SAndroid Build Coastguard Worker     RealTimedQueueWrapper(JavaVM* jvm) {
280*d57664e9SAndroid Build Coastguard Worker         mThread = std::thread([this, jvm]() {
281*d57664e9SAndroid Build Coastguard Worker             (void)getOrAttachJniEnv(jvm);
282*d57664e9SAndroid Build Coastguard Worker             runTimers();
283*d57664e9SAndroid Build Coastguard Worker         });
284*d57664e9SAndroid Build Coastguard Worker     }
~RealTimedQueueWrapper()285*d57664e9SAndroid Build Coastguard Worker     ~RealTimedQueueWrapper() final {
286*d57664e9SAndroid Build Coastguard Worker         CHECK(!mRunning) << "call stop first";
287*d57664e9SAndroid Build Coastguard Worker         CHECK(!mThread.joinable()) << "call stop first";
288*d57664e9SAndroid Build Coastguard Worker     }
289*d57664e9SAndroid Build Coastguard Worker 
addJob(MountId id,Milliseconds timeout,Job what)290*d57664e9SAndroid Build Coastguard Worker     void addJob(MountId id, Milliseconds timeout, Job what) final {
291*d57664e9SAndroid Build Coastguard Worker         const auto now = Clock::now();
292*d57664e9SAndroid Build Coastguard Worker         {
293*d57664e9SAndroid Build Coastguard Worker             std::unique_lock lock(mMutex);
294*d57664e9SAndroid Build Coastguard Worker             mJobs.insert(TimedJob{id, now + timeout, std::move(what)});
295*d57664e9SAndroid Build Coastguard Worker         }
296*d57664e9SAndroid Build Coastguard Worker         mCondition.notify_all();
297*d57664e9SAndroid Build Coastguard Worker     }
removeJobs(MountId id)298*d57664e9SAndroid Build Coastguard Worker     void removeJobs(MountId id) final {
299*d57664e9SAndroid Build Coastguard Worker         std::unique_lock lock(mMutex);
300*d57664e9SAndroid Build Coastguard Worker         std::erase_if(mJobs, [id](auto&& item) { return item.id == id; });
301*d57664e9SAndroid Build Coastguard Worker     }
stop()302*d57664e9SAndroid Build Coastguard Worker     void stop() final {
303*d57664e9SAndroid Build Coastguard Worker         {
304*d57664e9SAndroid Build Coastguard Worker             std::unique_lock lock(mMutex);
305*d57664e9SAndroid Build Coastguard Worker             mRunning = false;
306*d57664e9SAndroid Build Coastguard Worker         }
307*d57664e9SAndroid Build Coastguard Worker         mCondition.notify_all();
308*d57664e9SAndroid Build Coastguard Worker         mThread.join();
309*d57664e9SAndroid Build Coastguard Worker         mJobs.clear();
310*d57664e9SAndroid Build Coastguard Worker     }
311*d57664e9SAndroid Build Coastguard Worker 
312*d57664e9SAndroid Build Coastguard Worker private:
runTimers()313*d57664e9SAndroid Build Coastguard Worker     void runTimers() {
314*d57664e9SAndroid Build Coastguard Worker         static constexpr TimePoint kInfinityTs{Clock::duration::max()};
315*d57664e9SAndroid Build Coastguard Worker         std::unique_lock lock(mMutex);
316*d57664e9SAndroid Build Coastguard Worker         for (;;) {
317*d57664e9SAndroid Build Coastguard Worker             const TimePoint nextJobTs = mJobs.empty() ? kInfinityTs : mJobs.begin()->when;
318*d57664e9SAndroid Build Coastguard Worker             auto conditionPredicate = [this, oldNextJobTs = nextJobTs]() {
319*d57664e9SAndroid Build Coastguard Worker                 const auto now = Clock::now();
320*d57664e9SAndroid Build Coastguard Worker                 const auto newFirstJobTs = !mJobs.empty() ? mJobs.begin()->when : kInfinityTs;
321*d57664e9SAndroid Build Coastguard Worker                 return newFirstJobTs <= now || newFirstJobTs < oldNextJobTs || !mRunning;
322*d57664e9SAndroid Build Coastguard Worker             };
323*d57664e9SAndroid Build Coastguard Worker             // libcxx's implementation of wait_until() recalculates the 'until' time into
324*d57664e9SAndroid Build Coastguard Worker             // the wait duration and then goes back to the absolute timestamp when calling
325*d57664e9SAndroid Build Coastguard Worker             // pthread_cond_timedwait(); this back-and-forth calculation sometimes loses
326*d57664e9SAndroid Build Coastguard Worker             // the 'infinity' value because enough time passes in between, and instead
327*d57664e9SAndroid Build Coastguard Worker             // passes incorrect timestamp into the syscall, causing a crash.
328*d57664e9SAndroid Build Coastguard Worker             // Mitigating it by explicitly calling the non-timed wait here.
329*d57664e9SAndroid Build Coastguard Worker             if (mJobs.empty()) {
330*d57664e9SAndroid Build Coastguard Worker                 mCondition.wait(lock, conditionPredicate);
331*d57664e9SAndroid Build Coastguard Worker             } else {
332*d57664e9SAndroid Build Coastguard Worker                 mCondition.wait_until(lock, nextJobTs, conditionPredicate);
333*d57664e9SAndroid Build Coastguard Worker             }
334*d57664e9SAndroid Build Coastguard Worker             if (!mRunning) {
335*d57664e9SAndroid Build Coastguard Worker                 return;
336*d57664e9SAndroid Build Coastguard Worker             }
337*d57664e9SAndroid Build Coastguard Worker 
338*d57664e9SAndroid Build Coastguard Worker             const auto now = Clock::now();
339*d57664e9SAndroid Build Coastguard Worker             // Always re-acquire begin(). We can't use it after unlock as mTimedJobs can change.
340*d57664e9SAndroid Build Coastguard Worker             for (auto it = mJobs.begin(); it != mJobs.end() && it->when <= now;
341*d57664e9SAndroid Build Coastguard Worker                  it = mJobs.begin()) {
342*d57664e9SAndroid Build Coastguard Worker                 auto jobNode = mJobs.extract(it);
343*d57664e9SAndroid Build Coastguard Worker 
344*d57664e9SAndroid Build Coastguard Worker                 lock.unlock();
345*d57664e9SAndroid Build Coastguard Worker                 jobNode.value().what();
346*d57664e9SAndroid Build Coastguard Worker                 lock.lock();
347*d57664e9SAndroid Build Coastguard Worker             }
348*d57664e9SAndroid Build Coastguard Worker         }
349*d57664e9SAndroid Build Coastguard Worker     }
350*d57664e9SAndroid Build Coastguard Worker 
351*d57664e9SAndroid Build Coastguard Worker     struct TimedJob {
352*d57664e9SAndroid Build Coastguard Worker         MountId id;
353*d57664e9SAndroid Build Coastguard Worker         TimePoint when;
354*d57664e9SAndroid Build Coastguard Worker         Job what;
operator <(const TimedJob & lhs,const TimedJob & rhs)355*d57664e9SAndroid Build Coastguard Worker         friend bool operator<(const TimedJob& lhs, const TimedJob& rhs) {
356*d57664e9SAndroid Build Coastguard Worker             return lhs.when < rhs.when;
357*d57664e9SAndroid Build Coastguard Worker         }
358*d57664e9SAndroid Build Coastguard Worker     };
359*d57664e9SAndroid Build Coastguard Worker     bool mRunning = true;
360*d57664e9SAndroid Build Coastguard Worker     std::multiset<TimedJob> mJobs;
361*d57664e9SAndroid Build Coastguard Worker     std::condition_variable mCondition;
362*d57664e9SAndroid Build Coastguard Worker     std::mutex mMutex;
363*d57664e9SAndroid Build Coastguard Worker     std::thread mThread;
364*d57664e9SAndroid Build Coastguard Worker };
365*d57664e9SAndroid Build Coastguard Worker 
366*d57664e9SAndroid Build Coastguard Worker class RealFsWrapper final : public FsWrapper {
367*d57664e9SAndroid Build Coastguard Worker public:
368*d57664e9SAndroid Build Coastguard Worker     RealFsWrapper() = default;
369*d57664e9SAndroid Build Coastguard Worker     ~RealFsWrapper() = default;
370*d57664e9SAndroid Build Coastguard Worker 
listFilesRecursive(std::string_view directoryPath,FileCallback onFile) const371*d57664e9SAndroid Build Coastguard Worker     void listFilesRecursive(std::string_view directoryPath, FileCallback onFile) const final {
372*d57664e9SAndroid Build Coastguard Worker         for (const auto& entry : std::filesystem::recursive_directory_iterator(directoryPath)) {
373*d57664e9SAndroid Build Coastguard Worker             if (!entry.is_regular_file()) {
374*d57664e9SAndroid Build Coastguard Worker                 continue;
375*d57664e9SAndroid Build Coastguard Worker             }
376*d57664e9SAndroid Build Coastguard Worker             if (!onFile(entry.path().native())) {
377*d57664e9SAndroid Build Coastguard Worker                 break;
378*d57664e9SAndroid Build Coastguard Worker             }
379*d57664e9SAndroid Build Coastguard Worker         }
380*d57664e9SAndroid Build Coastguard Worker     }
381*d57664e9SAndroid Build Coastguard Worker };
382*d57664e9SAndroid Build Coastguard Worker 
383*d57664e9SAndroid Build Coastguard Worker class RealClockWrapper final : public ClockWrapper {
384*d57664e9SAndroid Build Coastguard Worker public:
385*d57664e9SAndroid Build Coastguard Worker     RealClockWrapper() = default;
386*d57664e9SAndroid Build Coastguard Worker     ~RealClockWrapper() = default;
387*d57664e9SAndroid Build Coastguard Worker 
now() const388*d57664e9SAndroid Build Coastguard Worker     TimePoint now() const final { return Clock::now(); }
389*d57664e9SAndroid Build Coastguard Worker };
390*d57664e9SAndroid Build Coastguard Worker 
RealServiceManager(sp<IServiceManager> serviceManager,JNIEnv * env)391*d57664e9SAndroid Build Coastguard Worker RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
392*d57664e9SAndroid Build Coastguard Worker       : mServiceManager(std::move(serviceManager)), mJvm(RealJniWrapper::getJvm(env)) {}
393*d57664e9SAndroid Build Coastguard Worker 
394*d57664e9SAndroid Build Coastguard Worker template <class INTERFACE>
getRealService(std::string_view serviceName) const395*d57664e9SAndroid Build Coastguard Worker sp<INTERFACE> RealServiceManager::getRealService(std::string_view serviceName) const {
396*d57664e9SAndroid Build Coastguard Worker     sp<IBinder> binder =
397*d57664e9SAndroid Build Coastguard Worker             mServiceManager->getService(String16(serviceName.data(), serviceName.size()));
398*d57664e9SAndroid Build Coastguard Worker     if (!binder) {
399*d57664e9SAndroid Build Coastguard Worker         return nullptr;
400*d57664e9SAndroid Build Coastguard Worker     }
401*d57664e9SAndroid Build Coastguard Worker     return interface_cast<INTERFACE>(binder);
402*d57664e9SAndroid Build Coastguard Worker }
403*d57664e9SAndroid Build Coastguard Worker 
getVoldService()404*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<VoldServiceWrapper> RealServiceManager::getVoldService() {
405*d57664e9SAndroid Build Coastguard Worker     sp<os::IVold> vold = RealServiceManager::getRealService<os::IVold>(kVoldServiceName);
406*d57664e9SAndroid Build Coastguard Worker     if (vold != 0) {
407*d57664e9SAndroid Build Coastguard Worker         return std::make_unique<RealVoldService>(vold);
408*d57664e9SAndroid Build Coastguard Worker     }
409*d57664e9SAndroid Build Coastguard Worker     return nullptr;
410*d57664e9SAndroid Build Coastguard Worker }
411*d57664e9SAndroid Build Coastguard Worker 
getDataLoaderManager()412*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<DataLoaderManagerWrapper> RealServiceManager::getDataLoaderManager() {
413*d57664e9SAndroid Build Coastguard Worker     sp<content::pm::IDataLoaderManager> manager =
414*d57664e9SAndroid Build Coastguard Worker             RealServiceManager::getRealService<content::pm::IDataLoaderManager>(
415*d57664e9SAndroid Build Coastguard Worker                     kDataLoaderManagerName);
416*d57664e9SAndroid Build Coastguard Worker     if (manager) {
417*d57664e9SAndroid Build Coastguard Worker         return std::make_unique<RealDataLoaderManager>(manager);
418*d57664e9SAndroid Build Coastguard Worker     }
419*d57664e9SAndroid Build Coastguard Worker     return nullptr;
420*d57664e9SAndroid Build Coastguard Worker }
421*d57664e9SAndroid Build Coastguard Worker 
getIncFs()422*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<IncFsWrapper> RealServiceManager::getIncFs() {
423*d57664e9SAndroid Build Coastguard Worker     return std::make_unique<RealIncFs>();
424*d57664e9SAndroid Build Coastguard Worker }
425*d57664e9SAndroid Build Coastguard Worker 
getAppOpsManager()426*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<AppOpsManagerWrapper> RealServiceManager::getAppOpsManager() {
427*d57664e9SAndroid Build Coastguard Worker     return std::make_unique<RealAppOpsManager>();
428*d57664e9SAndroid Build Coastguard Worker }
429*d57664e9SAndroid Build Coastguard Worker 
getJni()430*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<JniWrapper> RealServiceManager::getJni() {
431*d57664e9SAndroid Build Coastguard Worker     return std::make_unique<RealJniWrapper>(mJvm);
432*d57664e9SAndroid Build Coastguard Worker }
433*d57664e9SAndroid Build Coastguard Worker 
getLooper()434*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<LooperWrapper> RealServiceManager::getLooper() {
435*d57664e9SAndroid Build Coastguard Worker     return std::make_unique<RealLooperWrapper>();
436*d57664e9SAndroid Build Coastguard Worker }
437*d57664e9SAndroid Build Coastguard Worker 
getTimedQueue()438*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<TimedQueueWrapper> RealServiceManager::getTimedQueue() {
439*d57664e9SAndroid Build Coastguard Worker     return std::make_unique<RealTimedQueueWrapper>(mJvm);
440*d57664e9SAndroid Build Coastguard Worker }
441*d57664e9SAndroid Build Coastguard Worker 
getProgressUpdateJobQueue()442*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<TimedQueueWrapper> RealServiceManager::getProgressUpdateJobQueue() {
443*d57664e9SAndroid Build Coastguard Worker     return std::make_unique<RealTimedQueueWrapper>(mJvm);
444*d57664e9SAndroid Build Coastguard Worker }
445*d57664e9SAndroid Build Coastguard Worker 
getFs()446*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<FsWrapper> RealServiceManager::getFs() {
447*d57664e9SAndroid Build Coastguard Worker     return std::make_unique<RealFsWrapper>();
448*d57664e9SAndroid Build Coastguard Worker }
449*d57664e9SAndroid Build Coastguard Worker 
getClock()450*d57664e9SAndroid Build Coastguard Worker std::unique_ptr<ClockWrapper> RealServiceManager::getClock() {
451*d57664e9SAndroid Build Coastguard Worker     return std::make_unique<RealClockWrapper>();
452*d57664e9SAndroid Build Coastguard Worker }
453*d57664e9SAndroid Build Coastguard Worker 
getJavaVm(JNIEnv * env)454*d57664e9SAndroid Build Coastguard Worker static JavaVM* getJavaVm(JNIEnv* env) {
455*d57664e9SAndroid Build Coastguard Worker     CHECK(env);
456*d57664e9SAndroid Build Coastguard Worker     JavaVM* jvm = nullptr;
457*d57664e9SAndroid Build Coastguard Worker     env->GetJavaVM(&jvm);
458*d57664e9SAndroid Build Coastguard Worker     CHECK(jvm);
459*d57664e9SAndroid Build Coastguard Worker     return jvm;
460*d57664e9SAndroid Build Coastguard Worker }
461*d57664e9SAndroid Build Coastguard Worker 
getJniEnv(JavaVM * vm)462*d57664e9SAndroid Build Coastguard Worker static JNIEnv* getJniEnv(JavaVM* vm) {
463*d57664e9SAndroid Build Coastguard Worker     JNIEnv* env;
464*d57664e9SAndroid Build Coastguard Worker     if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
465*d57664e9SAndroid Build Coastguard Worker         return nullptr;
466*d57664e9SAndroid Build Coastguard Worker     }
467*d57664e9SAndroid Build Coastguard Worker     return env;
468*d57664e9SAndroid Build Coastguard Worker }
469*d57664e9SAndroid Build Coastguard Worker 
getOrAttachJniEnv(JavaVM * jvm)470*d57664e9SAndroid Build Coastguard Worker static JNIEnv* getOrAttachJniEnv(JavaVM* jvm) {
471*d57664e9SAndroid Build Coastguard Worker     if (!jvm) {
472*d57664e9SAndroid Build Coastguard Worker         LOG(ERROR) << "No JVM instance";
473*d57664e9SAndroid Build Coastguard Worker         return nullptr;
474*d57664e9SAndroid Build Coastguard Worker     }
475*d57664e9SAndroid Build Coastguard Worker 
476*d57664e9SAndroid Build Coastguard Worker     JNIEnv* env = getJniEnv(jvm);
477*d57664e9SAndroid Build Coastguard Worker     if (!env) {
478*d57664e9SAndroid Build Coastguard Worker         int result = jvm->AttachCurrentThread(&env, nullptr);
479*d57664e9SAndroid Build Coastguard Worker         if (result != JNI_OK) {
480*d57664e9SAndroid Build Coastguard Worker             LOG(ERROR) << "JVM thread attach failed: " << result;
481*d57664e9SAndroid Build Coastguard Worker             return nullptr;
482*d57664e9SAndroid Build Coastguard Worker         }
483*d57664e9SAndroid Build Coastguard Worker         struct VmDetacher {
484*d57664e9SAndroid Build Coastguard Worker             VmDetacher(JavaVM* vm) : mVm(vm) {}
485*d57664e9SAndroid Build Coastguard Worker             ~VmDetacher() { mVm->DetachCurrentThread(); }
486*d57664e9SAndroid Build Coastguard Worker 
487*d57664e9SAndroid Build Coastguard Worker         private:
488*d57664e9SAndroid Build Coastguard Worker             JavaVM* const mVm;
489*d57664e9SAndroid Build Coastguard Worker         };
490*d57664e9SAndroid Build Coastguard Worker         static thread_local VmDetacher detacher(jvm);
491*d57664e9SAndroid Build Coastguard Worker     }
492*d57664e9SAndroid Build Coastguard Worker 
493*d57664e9SAndroid Build Coastguard Worker     return env;
494*d57664e9SAndroid Build Coastguard Worker }
495*d57664e9SAndroid Build Coastguard Worker 
RealJniWrapper(JavaVM * jvm)496*d57664e9SAndroid Build Coastguard Worker RealJniWrapper::RealJniWrapper(JavaVM* jvm) : mJvm(jvm) {
497*d57664e9SAndroid Build Coastguard Worker     CHECK(!!mJvm) << "JVM is unavailable";
498*d57664e9SAndroid Build Coastguard Worker }
499*d57664e9SAndroid Build Coastguard Worker 
initializeForCurrentThread() const500*d57664e9SAndroid Build Coastguard Worker void RealJniWrapper::initializeForCurrentThread() const {
501*d57664e9SAndroid Build Coastguard Worker     (void)getOrAttachJniEnv(mJvm);
502*d57664e9SAndroid Build Coastguard Worker }
503*d57664e9SAndroid Build Coastguard Worker 
getJvm(JNIEnv * env)504*d57664e9SAndroid Build Coastguard Worker JavaVM* RealJniWrapper::getJvm(JNIEnv* env) {
505*d57664e9SAndroid Build Coastguard Worker     return getJavaVm(env);
506*d57664e9SAndroid Build Coastguard Worker }
507*d57664e9SAndroid Build Coastguard Worker 
508*d57664e9SAndroid Build Coastguard Worker } // namespace android::incremental
509