blob: bf8e696a264cfb2fa7c2bbcd316db10ecafc769b [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 Zubrytskyi86321402020-04-09 19:22:30 -070021#include <android-base/logging.h>
Songchun Fan3c82a302019-11-29 14:23:45 -080022#include <utils/String16.h>
23
Songchun Fan3c82a302019-11-29 14:23:45 -080024using namespace std::literals;
25
26namespace android::os::incremental {
27
28static constexpr auto kVoldServiceName = "vold"sv;
Songchun Fan68645c42020-02-27 15:57:35 -080029static constexpr auto kDataLoaderManagerName = "dataloader_manager"sv;
Songchun Fan3c82a302019-11-29 14:23:45 -080030
Yurii Zubrytskyi86321402020-04-09 19:22:30 -070031class RealVoldService : public VoldServiceWrapper {
32public:
33 RealVoldService(const sp<os::IVold> vold) : mInterface(std::move(vold)) {}
34 ~RealVoldService() = default;
35 binder::Status mountIncFs(const std::string& backingPath, const std::string& targetDir,
36 int32_t flags,
37 IncrementalFileSystemControlParcel* _aidl_return) const final {
38 return mInterface->mountIncFs(backingPath, targetDir, flags, _aidl_return);
39 }
40 binder::Status unmountIncFs(const std::string& dir) const final {
41 return mInterface->unmountIncFs(dir);
42 }
43 binder::Status bindMount(const std::string& sourceDir,
44 const std::string& targetDir) const final {
45 return mInterface->bindMount(sourceDir, targetDir);
46 }
47 binder::Status setIncFsMountOptions(
48 const ::android::os::incremental::IncrementalFileSystemControlParcel& control,
49 bool enableReadLogs) const final {
50 return mInterface->setIncFsMountOptions(control, enableReadLogs);
51 }
52
53private:
54 sp<os::IVold> mInterface;
55};
56
57class RealDataLoaderManager : public DataLoaderManagerWrapper {
58public:
59 RealDataLoaderManager(const sp<content::pm::IDataLoaderManager> manager)
60 : mInterface(manager) {}
61 ~RealDataLoaderManager() = default;
62 binder::Status initializeDataLoader(MountId mountId, const DataLoaderParamsParcel& params,
63 const FileSystemControlParcel& control,
64 const sp<IDataLoaderStatusListener>& listener,
65 bool* _aidl_return) const final {
66 return mInterface->initializeDataLoader(mountId, params, control, listener, _aidl_return);
67 }
68 binder::Status getDataLoader(MountId mountId, sp<IDataLoader>* _aidl_return) const final {
69 return mInterface->getDataLoader(mountId, _aidl_return);
70 }
71 binder::Status destroyDataLoader(MountId mountId) const final {
72 return mInterface->destroyDataLoader(mountId);
73 }
74
75private:
76 sp<content::pm::IDataLoaderManager> mInterface;
77};
78
79class RealAppOpsManager : public AppOpsManagerWrapper {
80public:
81 ~RealAppOpsManager() = default;
82 binder::Status checkPermission(const char* permission, const char* operation,
83 const char* package) const final {
84 return android::incremental::CheckPermissionForDataDelivery(permission, operation, package);
85 }
86 void startWatchingMode(int32_t op, const String16& packageName,
87 const sp<IAppOpsCallback>& callback) final {
88 mAppOpsManager.startWatchingMode(op, packageName, callback);
89 }
90 void stopWatchingMode(const sp<IAppOpsCallback>& callback) final {
91 mAppOpsManager.stopWatchingMode(callback);
92 }
93
94private:
95 android::AppOpsManager mAppOpsManager;
96};
97
98class RealJniWrapper final : public JniWrapper {
99public:
100 RealJniWrapper(JavaVM* jvm);
101 void initializeForCurrentThread() const final;
102
103 static JavaVM* getJvm(JNIEnv* env);
104
105private:
106 JavaVM* const mJvm;
107};
108
109class RealIncFs : public IncFsWrapper {
110public:
111 RealIncFs() = default;
112 ~RealIncFs() = default;
113 Control createControl(IncFsFd cmd, IncFsFd pendingReads, IncFsFd logs) const final {
114 return incfs::createControl(cmd, pendingReads, logs);
115 }
116 ErrorCode makeFile(const Control& control, std::string_view path, int mode, FileId id,
117 NewFileParams params) const final {
118 return incfs::makeFile(control, path, mode, id, params);
119 }
120 ErrorCode makeDir(const Control& control, std::string_view path, int mode) const final {
121 return incfs::makeDir(control, path, mode);
122 }
123 RawMetadata getMetadata(const Control& control, FileId fileid) const final {
124 return incfs::getMetadata(control, fileid);
125 }
126 RawMetadata getMetadata(const Control& control, std::string_view path) const final {
127 return incfs::getMetadata(control, path);
128 }
129 FileId getFileId(const Control& control, std::string_view path) const final {
130 return incfs::getFileId(control, path);
131 }
132 ErrorCode link(const Control& control, std::string_view from, std::string_view to) const final {
133 return incfs::link(control, from, to);
134 }
135 ErrorCode unlink(const Control& control, std::string_view path) const final {
136 return incfs::unlink(control, path);
137 }
138 base::unique_fd openForSpecialOps(const Control& control, FileId id) const final {
139 return base::unique_fd{incfs::openForSpecialOps(control, id).release()};
140 }
141 ErrorCode writeBlocks(Span<const DataBlock> blocks) const final {
142 return incfs::writeBlocks(blocks);
143 }
144};
145
146RealServiceManager::RealServiceManager(sp<IServiceManager> serviceManager, JNIEnv* env)
147 : mServiceManager(std::move(serviceManager)), mJvm(RealJniWrapper::getJvm(env)) {}
Songchun Fan3c82a302019-11-29 14:23:45 -0800148
149template <class INTERFACE>
150sp<INTERFACE> RealServiceManager::getRealService(std::string_view serviceName) const {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800151 sp<IBinder> binder =
152 mServiceManager->getService(String16(serviceName.data(), serviceName.size()));
153 if (!binder) {
154 return nullptr;
Songchun Fan3c82a302019-11-29 14:23:45 -0800155 }
156 return interface_cast<INTERFACE>(binder);
157}
158
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800159std::unique_ptr<VoldServiceWrapper> RealServiceManager::getVoldService() {
Songchun Fan3c82a302019-11-29 14:23:45 -0800160 sp<os::IVold> vold = RealServiceManager::getRealService<os::IVold>(kVoldServiceName);
161 if (vold != 0) {
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800162 return std::make_unique<RealVoldService>(vold);
Songchun Fan3c82a302019-11-29 14:23:45 -0800163 }
164 return nullptr;
165}
166
Songchun Fan68645c42020-02-27 15:57:35 -0800167std::unique_ptr<DataLoaderManagerWrapper> RealServiceManager::getDataLoaderManager() {
168 sp<IDataLoaderManager> manager =
169 RealServiceManager::getRealService<IDataLoaderManager>(kDataLoaderManagerName);
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800170 if (manager) {
Songchun Fan68645c42020-02-27 15:57:35 -0800171 return std::make_unique<RealDataLoaderManager>(manager);
Songchun Fan3c82a302019-11-29 14:23:45 -0800172 }
173 return nullptr;
174}
175
Yurii Zubrytskyi4a25dfb2020-01-10 11:53:24 -0800176std::unique_ptr<IncFsWrapper> RealServiceManager::getIncFs() {
177 return std::make_unique<RealIncFs>();
Songchun Fan3c82a302019-11-29 14:23:45 -0800178}
179
Alex Buynytskyy96e350b2020-04-02 20:03:47 -0700180std::unique_ptr<AppOpsManagerWrapper> RealServiceManager::getAppOpsManager() {
181 return std::make_unique<RealAppOpsManager>();
182}
183
Yurii Zubrytskyi86321402020-04-09 19:22:30 -0700184std::unique_ptr<JniWrapper> RealServiceManager::getJni() {
185 return std::make_unique<RealJniWrapper>(mJvm);
186}
187
188static JavaVM* getJavaVm(JNIEnv* env) {
189 CHECK(env);
190 JavaVM* jvm = nullptr;
191 env->GetJavaVM(&jvm);
192 CHECK(jvm);
193 return jvm;
194}
195
196static JNIEnv* getJniEnv(JavaVM* vm) {
197 JNIEnv* env;
198 if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
199 return nullptr;
200 }
201 return env;
202}
203
204static JNIEnv* getOrAttachJniEnv(JavaVM* jvm) {
205 if (!jvm) {
206 LOG(ERROR) << "No JVM instance";
207 return nullptr;
208 }
209
210 JNIEnv* env = getJniEnv(jvm);
211 if (!env) {
212 int result = jvm->AttachCurrentThread(&env, nullptr);
213 if (result != JNI_OK) {
214 LOG(ERROR) << "JVM thread attach failed: " << result;
215 return nullptr;
216 }
217 struct VmDetacher {
218 VmDetacher(JavaVM* vm) : mVm(vm) {}
219 ~VmDetacher() { mVm->DetachCurrentThread(); }
220
221 private:
222 JavaVM* const mVm;
223 };
224 static thread_local VmDetacher detacher(jvm);
225 }
226
227 return env;
228}
229
230RealJniWrapper::RealJniWrapper(JavaVM* jvm) : mJvm(jvm) {
231 CHECK(!!mJvm) << "JVM is unavailable";
232}
233
234void RealJniWrapper::initializeForCurrentThread() const {
235 (void)getOrAttachJniEnv(mJvm);
236}
237
238JavaVM* RealJniWrapper::getJvm(JNIEnv* env) {
239 return getJavaVm(env);
240}
241
Songchun Fan3c82a302019-11-29 14:23:45 -0800242} // namespace android::os::incremental