blob: bb26c1f931593389b13c0811a265bc3ee8b2eea4 [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
17#include "BinderIncrementalService.h"
18
19#include <binder/IResultReceiver.h>
20#include <incfs.h>
21
22#include "ServiceWrappers.h"
23#include "jni.h"
24#include "nativehelper/JNIHelp.h"
25#include "path.h"
26
27using namespace std::literals;
28using namespace android::incremental;
29
30namespace android::os::incremental {
31
32static constexpr auto kAndroidDataEnv = "ANDROID_DATA"sv;
33static constexpr auto kDataDir = "/data"sv;
34static constexpr auto kIncrementalSubDir = "incremental"sv;
35
36static std::string getIncrementalDir() {
37 const char* dataDir = getenv(kAndroidDataEnv.data());
38 if (!dataDir || !*dataDir) {
39 dataDir = kDataDir.data();
40 }
41 return path::normalize(path::join(dataDir, kIncrementalSubDir));
42}
43
44static bool incFsEnabled() {
45 // TODO(b/136132412): use vold to check /sys/fs/incfs/version (per selinux compliance)
46 return incfs::enabled();
47}
48
49static bool incFsVersionValid(const sp<IVold>& vold) {
50 int version = -1;
51 auto status = vold->incFsVersion(&version);
52 if (!status.isOk() || version <= 0) {
53 return false;
54 }
55 return true;
56}
57
58BinderIncrementalService::BinderIncrementalService(const sp<IServiceManager>& sm)
59 : mImpl(RealServiceManager(sm), getIncrementalDir()) {}
60
61BinderIncrementalService* BinderIncrementalService::start() {
62 if (!incFsEnabled()) {
63 return nullptr;
64 }
65
66 IPCThreadState::self()->disableBackgroundScheduling(true);
67 sp<IServiceManager> sm(defaultServiceManager());
68 if (!sm) {
69 return nullptr;
70 }
71
72 sp<IBinder> voldBinder(sm->getService(String16("vold")));
73 if (voldBinder == nullptr) {
74 return nullptr;
75 }
76 sp<IVold> vold = interface_cast<IVold>(voldBinder);
77 if (!incFsVersionValid(vold)) {
78 return nullptr;
79 }
80
81 sp<BinderIncrementalService> self(new BinderIncrementalService(sm));
82 status_t ret = sm->addService(String16{getServiceName()}, self);
83 if (ret != android::OK) {
84 return nullptr;
85 }
86 sp<ProcessState> ps(ProcessState::self());
87 ps->startThreadPool();
88 ps->giveThreadPoolName();
89 return self.get();
90}
91
92status_t BinderIncrementalService::dump(int fd, const Vector<String16>& args) {
93 return OK;
94}
95
96void BinderIncrementalService::onSystemReady() {
97 mImpl.onSystemReady();
98}
99
100static binder::Status ok() {
101 return binder::Status::ok();
102}
103
104binder::Status BinderIncrementalService::openStorage(const std::string& path,
105 int32_t* _aidl_return) {
106 *_aidl_return = mImpl.openStorage(path);
107 return ok();
108}
109
110binder::Status BinderIncrementalService::createStorage(
111 const std::string& path, const DataLoaderParamsParcel& params,
112 int32_t createMode, int32_t* _aidl_return) {
113 *_aidl_return =
114 mImpl.createStorage(path, const_cast<DataLoaderParamsParcel&&>(params),
115 android::incremental::IncrementalService::CreateOptions(
116 createMode));
117 return ok();
118}
119
120binder::Status BinderIncrementalService::createLinkedStorage(const std::string& path,
121 int32_t otherStorageId,
122 int32_t createMode,
123 int32_t* _aidl_return) {
124 *_aidl_return =
125 mImpl.createLinkedStorage(path, otherStorageId,
126 android::incremental::IncrementalService::CreateOptions(
127 createMode));
128 return ok();
129}
130
131binder::Status BinderIncrementalService::makeBindMount(int32_t storageId,
132 const std::string& pathUnderStorage,
133 const std::string& targetFullPath,
134 int32_t bindType, int32_t* _aidl_return) {
135 *_aidl_return = mImpl.bind(storageId, pathUnderStorage, targetFullPath,
136 android::incremental::IncrementalService::BindKind(bindType));
137 return ok();
138}
139
140binder::Status BinderIncrementalService::deleteBindMount(int32_t storageId,
141 const std::string& targetFullPath,
142 int32_t* _aidl_return) {
143 *_aidl_return = mImpl.unbind(storageId, targetFullPath);
144 return ok();
145}
146
147binder::Status BinderIncrementalService::deleteStorage(int32_t storageId) {
148 mImpl.deleteStorage(storageId);
149 return ok();
150}
151
152binder::Status BinderIncrementalService::makeDirectory(int32_t storageId,
153 const std::string& pathUnderStorage,
154 int32_t* _aidl_return) {
155 auto inode = mImpl.makeDir(storageId, pathUnderStorage);
156 *_aidl_return = inode < 0 ? inode : 0;
157 return ok();
158}
159
160binder::Status BinderIncrementalService::makeDirectories(int32_t storageId,
161 const std::string& pathUnderStorage,
162 int32_t* _aidl_return) {
163 auto inode = mImpl.makeDirs(storageId, pathUnderStorage);
164 *_aidl_return = inode < 0 ? inode : 0;
165 return ok();
166}
167
168binder::Status BinderIncrementalService::makeFile(int32_t storageId,
169 const std::string& pathUnderStorage, int64_t size,
170 const std::vector<uint8_t>& metadata,
171 int32_t* _aidl_return) {
172 auto inode = mImpl.makeFile(storageId, pathUnderStorage, size,
173 {(const char*)metadata.data(), metadata.size()}, {});
174 *_aidl_return = inode < 0 ? inode : 0;
175 return ok();
176}
177binder::Status BinderIncrementalService::makeFileFromRange(
178 int32_t storageId, const std::string& pathUnderStorage,
179 const std::string& sourcePathUnderStorage, int64_t start, int64_t end,
180 int32_t* _aidl_return) {
181 // TODO(b/136132412): implement this
182 *_aidl_return = -1;
183 return ok();
184}
185binder::Status BinderIncrementalService::makeLink(int32_t sourceStorageId,
186 const std::string& relativeSourcePath,
187 int32_t destStorageId,
188 const std::string& relativeDestPath,
189 int32_t* _aidl_return) {
190 auto sourceInode = mImpl.nodeFor(sourceStorageId, relativeSourcePath);
191 auto [targetParentInode, name] = mImpl.parentAndNameFor(destStorageId, relativeDestPath);
192 *_aidl_return = mImpl.link(sourceStorageId, sourceInode, targetParentInode, name);
193 return ok();
194}
195binder::Status BinderIncrementalService::unlink(int32_t storageId,
196 const std::string& pathUnderStorage,
197 int32_t* _aidl_return) {
198 auto [parentNode, name] = mImpl.parentAndNameFor(storageId, pathUnderStorage);
199 *_aidl_return = mImpl.unlink(storageId, parentNode, name);
200 return ok();
201}
202binder::Status BinderIncrementalService::isFileRangeLoaded(int32_t storageId,
203 const std::string& relativePath,
204 int64_t start, int64_t end,
205 bool* _aidl_return) {
206 *_aidl_return = false;
207 return ok();
208}
209binder::Status BinderIncrementalService::getFileMetadata(int32_t storageId,
210 const std::string& relativePath,
211 std::vector<uint8_t>* _aidl_return) {
212 auto inode = mImpl.nodeFor(storageId, relativePath);
213 auto metadata = mImpl.getMetadata(storageId, inode);
214 _aidl_return->assign(metadata.begin(), metadata.end());
215 return ok();
216}
217binder::Status BinderIncrementalService::startLoading(int32_t storageId, bool* _aidl_return) {
218 *_aidl_return = mImpl.startLoading(storageId);
219 return ok();
220}
221} // namespace android::os::incremental
222
223jlong Incremental_IncrementalService_Start() {
224 return (jlong)android::os::incremental::BinderIncrementalService::start();
225}
226void Incremental_IncrementalService_OnSystemReady(jlong self) {
227 if (self) {
228 ((android::os::incremental::BinderIncrementalService*)self)->onSystemReady();
229 }
230}