1 //
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 #if !defined(__ANDROID_RECOVERY__)
18 #include <android-base/logging.h>
19 #include <android-base/properties.h>
20 #include <android/gsi/BnProgressCallback.h>
21 #include <android/gsi/IGsiService.h>
22 #include <libfiemap/image_manager.h>
23 #include <libgsi/libgsi.h>
24 #include <libgsi/libgsid.h>
25
26 namespace android {
27 namespace fiemap {
28
29 using namespace android::gsi;
30 using namespace std::chrono_literals;
31
32 class ProgressCallback final : public BnProgressCallback {
33 public:
ProgressCallback(std::function<bool (uint64_t,uint64_t)> && callback)34 ProgressCallback(std::function<bool(uint64_t, uint64_t)>&& callback)
35 : callback_(std::move(callback)) {
36 CHECK(callback_);
37 }
onProgress(int64_t current,int64_t total)38 android::binder::Status onProgress(int64_t current, int64_t total) {
39 if (callback_(static_cast<uint64_t>(current), static_cast<uint64_t>(total))) {
40 return android::binder::Status::ok();
41 }
42 return android::binder::Status::fromServiceSpecificError(UNKNOWN_ERROR,
43 "Progress callback failed");
44 }
45
46 private:
47 std::function<bool(uint64_t, uint64_t)> callback_;
48 };
49
50 class ImageManagerBinder final : public IImageManager {
51 public:
52 ImageManagerBinder(android::sp<IGsiService>&& service, android::sp<IImageService>&& manager);
53 FiemapStatus CreateBackingImage(const std::string& name, uint64_t size, int flags,
54 std::function<bool(uint64_t, uint64_t)>&& on_progress) override;
55 bool DeleteBackingImage(const std::string& name) override;
56 bool MapImageDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms,
57 std::string* path) override;
58 bool UnmapImageDevice(const std::string& name) override;
59 bool BackingImageExists(const std::string& name) override;
60 bool IsImageMapped(const std::string& name) override;
61 bool MapImageWithDeviceMapper(const IPartitionOpener& opener, const std::string& name,
62 std::string* dev) override;
63 FiemapStatus ZeroFillNewImage(const std::string& name, uint64_t bytes) override;
64 bool RemoveAllImages() override;
65 bool DisableImage(const std::string& name) override;
66 bool RemoveDisabledImages() override;
67 bool GetMappedImageDevice(const std::string& name, std::string* device) override;
68 bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override;
69 bool IsImageDisabled(const std::string& name) override;
70
71 std::vector<std::string> GetAllBackingImages() override;
72
73 private:
74 android::sp<IGsiService> service_;
75 android::sp<IImageService> manager_;
76 };
77
ToFiemapStatus(const char * func,const binder::Status & status)78 static FiemapStatus ToFiemapStatus(const char* func, const binder::Status& status) {
79 if (!status.isOk()) {
80 LOG(ERROR) << func << " binder returned: " << status.toString8().c_str();
81 if (status.serviceSpecificErrorCode() != 0) {
82 return FiemapStatus::FromErrorCode(status.serviceSpecificErrorCode());
83 } else {
84 return FiemapStatus::Error();
85 }
86 }
87 return FiemapStatus::Ok();
88 }
89
ImageManagerBinder(android::sp<IGsiService> && service,android::sp<IImageService> && manager)90 ImageManagerBinder::ImageManagerBinder(android::sp<IGsiService>&& service,
91 android::sp<IImageService>&& manager)
92 : service_(std::move(service)), manager_(std::move(manager)) {}
93
CreateBackingImage(const std::string & name,uint64_t size,int flags,std::function<bool (uint64_t,uint64_t)> && on_progress)94 FiemapStatus ImageManagerBinder::CreateBackingImage(
95 const std::string& name, uint64_t size, int flags,
96 std::function<bool(uint64_t, uint64_t)>&& on_progress) {
97 sp<IProgressCallback> callback = nullptr;
98 if (on_progress) {
99 callback = new ProgressCallback(std::move(on_progress));
100 }
101 auto status = manager_->createBackingImage(name, size, flags, callback);
102 return ToFiemapStatus(__PRETTY_FUNCTION__, status);
103 }
104
DeleteBackingImage(const std::string & name)105 bool ImageManagerBinder::DeleteBackingImage(const std::string& name) {
106 auto status = manager_->deleteBackingImage(name);
107 if (!status.isOk()) {
108 LOG(ERROR) << __PRETTY_FUNCTION__
109 << " binder returned: " << status.exceptionMessage().c_str();
110 return false;
111 }
112 return true;
113 }
114
MapImageDevice(const std::string & name,const std::chrono::milliseconds & timeout_ms,std::string * path)115 bool ImageManagerBinder::MapImageDevice(const std::string& name,
116 const std::chrono::milliseconds& timeout_ms,
117 std::string* path) {
118 int32_t timeout_ms_count =
119 static_cast<int32_t>(std::clamp<typename std::chrono::milliseconds::rep>(
120 timeout_ms.count(), INT32_MIN, INT32_MAX));
121 MappedImage map;
122 auto status = manager_->mapImageDevice(name, timeout_ms_count, &map);
123 if (!status.isOk()) {
124 LOG(ERROR) << __PRETTY_FUNCTION__
125 << " binder returned: " << status.exceptionMessage().c_str();
126 return false;
127 }
128 *path = map.path;
129 return true;
130 }
131
UnmapImageDevice(const std::string & name)132 bool ImageManagerBinder::UnmapImageDevice(const std::string& name) {
133 auto status = manager_->unmapImageDevice(name);
134 if (!status.isOk()) {
135 LOG(ERROR) << __PRETTY_FUNCTION__
136 << " binder returned: " << status.exceptionMessage().c_str();
137 return false;
138 }
139 return true;
140 }
141
BackingImageExists(const std::string & name)142 bool ImageManagerBinder::BackingImageExists(const std::string& name) {
143 bool retval;
144 auto status = manager_->backingImageExists(name, &retval);
145 if (!status.isOk()) {
146 LOG(ERROR) << __PRETTY_FUNCTION__
147 << " binder returned: " << status.exceptionMessage().c_str();
148 return false;
149 }
150 return retval;
151 }
152
IsImageMapped(const std::string & name)153 bool ImageManagerBinder::IsImageMapped(const std::string& name) {
154 bool retval;
155 auto status = manager_->isImageMapped(name, &retval);
156 if (!status.isOk()) {
157 LOG(ERROR) << __PRETTY_FUNCTION__
158 << " binder returned: " << status.exceptionMessage().c_str();
159 return false;
160 }
161 return retval;
162 }
163
MapImageWithDeviceMapper(const IPartitionOpener & opener,const std::string & name,std::string * dev)164 bool ImageManagerBinder::MapImageWithDeviceMapper(const IPartitionOpener& opener,
165 const std::string& name, std::string* dev) {
166 (void)opener;
167 (void)name;
168 (void)dev;
169 LOG(ERROR) << "MapImageWithDeviceMapper is not available over binder.";
170 return false;
171 }
172
GetAllBackingImages()173 std::vector<std::string> ImageManagerBinder::GetAllBackingImages() {
174 std::vector<std::string> retval;
175 auto status = manager_->getAllBackingImages(&retval);
176 if (!status.isOk()) {
177 LOG(ERROR) << __PRETTY_FUNCTION__
178 << " binder returned: " << status.exceptionMessage().c_str();
179 }
180 return retval;
181 }
182
ZeroFillNewImage(const std::string & name,uint64_t bytes)183 FiemapStatus ImageManagerBinder::ZeroFillNewImage(const std::string& name, uint64_t bytes) {
184 auto status = manager_->zeroFillNewImage(name, bytes);
185 return ToFiemapStatus(__PRETTY_FUNCTION__, status);
186 }
187
RemoveAllImages()188 bool ImageManagerBinder::RemoveAllImages() {
189 auto status = manager_->removeAllImages();
190 if (!status.isOk()) {
191 LOG(ERROR) << __PRETTY_FUNCTION__
192 << " binder returned: " << status.exceptionMessage().c_str();
193 return false;
194 }
195 return true;
196 }
197
DisableImage(const std::string & name)198 bool ImageManagerBinder::DisableImage(const std::string& name) {
199 auto status = manager_->disableImage(name);
200 if (!status.isOk()) {
201 LOG(ERROR) << __PRETTY_FUNCTION__
202 << " binder returned: " << status.exceptionMessage().c_str();
203 return false;
204 }
205 return true;
206 }
207
RemoveDisabledImages()208 bool ImageManagerBinder::RemoveDisabledImages() {
209 auto status = manager_->removeDisabledImages();
210 if (!status.isOk()) {
211 LOG(ERROR) << __PRETTY_FUNCTION__
212 << " binder returned: " << status.exceptionMessage().c_str();
213 return false;
214 }
215 return true;
216 }
217
GetMappedImageDevice(const std::string & name,std::string * device)218 bool ImageManagerBinder::GetMappedImageDevice(const std::string& name, std::string* device) {
219 auto status = manager_->getMappedImageDevice(name, device);
220 if (!status.isOk()) {
221 LOG(ERROR) << __PRETTY_FUNCTION__
222 << " binder returned: " << status.exceptionMessage().c_str();
223 return false;
224 }
225 return !device->empty();
226 }
227
IsImageDisabled(const std::string & name)228 bool ImageManagerBinder::IsImageDisabled(const std::string& name) {
229 bool retval;
230 auto status = manager_->isImageDisabled(name, &retval);
231 if (!status.isOk()) {
232 LOG(ERROR) << __PRETTY_FUNCTION__
233 << " binder returned: " << status.exceptionMessage().c_str();
234 return false;
235 }
236 return retval;
237 }
238
MapAllImages(const std::function<bool (std::set<std::string>)> &)239 bool ImageManagerBinder::MapAllImages(const std::function<bool(std::set<std::string>)>&) {
240 LOG(ERROR) << __PRETTY_FUNCTION__ << " not available over binder";
241 return false;
242 }
243
Open(const std::string & dir,const std::chrono::milliseconds &,const DeviceInfo &)244 std::unique_ptr<IImageManager> IImageManager::Open(const std::string& dir,
245 const std::chrono::milliseconds& /*timeout_ms*/,
246 const DeviceInfo&) {
247 android::sp<IGsiService> service = android::gsi::GetGsiService();
248 android::sp<IImageService> manager;
249
250 auto status = service->openImageService(dir, &manager);
251 if (!status.isOk() || !manager) {
252 LOG(ERROR) << "Could not acquire IImageManager: " << status.exceptionMessage().c_str();
253 return nullptr;
254 }
255 return std::make_unique<ImageManagerBinder>(std::move(service), std::move(manager));
256 }
257
258 } // namespace fiemap
259 } // namespace android
260
261 #endif // __ANDROID_RECOVERY__
262