• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 DisableAllImages() override;
66     bool DisableImage(const std::string& name) override;
67     bool RemoveDisabledImages() override;
68     bool GetMappedImageDevice(const std::string& name, std::string* device) override;
69     bool MapAllImages(const std::function<bool(std::set<std::string>)>& init) override;
70     bool IsImageDisabled(const std::string& name) override;
71 
72     std::vector<std::string> GetAllBackingImages() override;
73 
74   private:
75     android::sp<IGsiService> service_;
76     android::sp<IImageService> manager_;
77 };
78 
ToFiemapStatus(const char * func,const binder::Status & status)79 static FiemapStatus ToFiemapStatus(const char* func, const binder::Status& status) {
80     if (!status.isOk()) {
81         LOG(ERROR) << func << " binder returned: " << status.toString8().c_str();
82         if (status.serviceSpecificErrorCode() != 0) {
83             return FiemapStatus::FromErrorCode(status.serviceSpecificErrorCode());
84         } else {
85             return FiemapStatus::Error();
86         }
87     }
88     return FiemapStatus::Ok();
89 }
90 
ImageManagerBinder(android::sp<IGsiService> && service,android::sp<IImageService> && manager)91 ImageManagerBinder::ImageManagerBinder(android::sp<IGsiService>&& service,
92                                        android::sp<IImageService>&& manager)
93     : service_(std::move(service)), manager_(std::move(manager)) {}
94 
CreateBackingImage(const std::string & name,uint64_t size,int flags,std::function<bool (uint64_t,uint64_t)> && on_progress)95 FiemapStatus ImageManagerBinder::CreateBackingImage(
96         const std::string& name, uint64_t size, int flags,
97         std::function<bool(uint64_t, uint64_t)>&& on_progress) {
98     sp<IProgressCallback> callback = nullptr;
99     if (on_progress) {
100         callback = new ProgressCallback(std::move(on_progress));
101     }
102     auto status = manager_->createBackingImage(name, size, flags, callback);
103     return ToFiemapStatus(__PRETTY_FUNCTION__, status);
104 }
105 
DeleteBackingImage(const std::string & name)106 bool ImageManagerBinder::DeleteBackingImage(const std::string& name) {
107     auto status = manager_->deleteBackingImage(name);
108     if (!status.isOk()) {
109         LOG(ERROR) << __PRETTY_FUNCTION__
110                    << " binder returned: " << status.exceptionMessage().c_str();
111         return false;
112     }
113     return true;
114 }
115 
MapImageDevice(const std::string & name,const std::chrono::milliseconds & timeout_ms,std::string * path)116 bool ImageManagerBinder::MapImageDevice(const std::string& name,
117                                         const std::chrono::milliseconds& timeout_ms,
118                                         std::string* path) {
119     int32_t timeout_ms_count =
120             static_cast<int32_t>(std::clamp<typename std::chrono::milliseconds::rep>(
121                     timeout_ms.count(), INT32_MIN, INT32_MAX));
122     MappedImage map;
123     auto status = manager_->mapImageDevice(name, timeout_ms_count, &map);
124     if (!status.isOk()) {
125         LOG(ERROR) << __PRETTY_FUNCTION__
126                    << " binder returned: " << status.exceptionMessage().c_str();
127         return false;
128     }
129     *path = map.path;
130     return true;
131 }
132 
UnmapImageDevice(const std::string & name)133 bool ImageManagerBinder::UnmapImageDevice(const std::string& name) {
134     auto status = manager_->unmapImageDevice(name);
135     if (!status.isOk()) {
136         LOG(ERROR) << __PRETTY_FUNCTION__
137                    << " binder returned: " << status.exceptionMessage().c_str();
138         return false;
139     }
140     return true;
141 }
142 
BackingImageExists(const std::string & name)143 bool ImageManagerBinder::BackingImageExists(const std::string& name) {
144     bool retval;
145     auto status = manager_->backingImageExists(name, &retval);
146     if (!status.isOk()) {
147         LOG(ERROR) << __PRETTY_FUNCTION__
148                    << " binder returned: " << status.exceptionMessage().c_str();
149         return false;
150     }
151     return retval;
152 }
153 
IsImageMapped(const std::string & name)154 bool ImageManagerBinder::IsImageMapped(const std::string& name) {
155     bool retval;
156     auto status = manager_->isImageMapped(name, &retval);
157     if (!status.isOk()) {
158         LOG(ERROR) << __PRETTY_FUNCTION__
159                    << " binder returned: " << status.exceptionMessage().c_str();
160         return false;
161     }
162     return retval;
163 }
164 
MapImageWithDeviceMapper(const IPartitionOpener & opener,const std::string & name,std::string * dev)165 bool ImageManagerBinder::MapImageWithDeviceMapper(const IPartitionOpener& opener,
166                                                   const std::string& name, std::string* dev) {
167     (void)opener;
168     (void)name;
169     (void)dev;
170     LOG(ERROR) << "MapImageWithDeviceMapper is not available over binder.";
171     return false;
172 }
173 
GetAllBackingImages()174 std::vector<std::string> ImageManagerBinder::GetAllBackingImages() {
175     std::vector<std::string> retval;
176     auto status = manager_->getAllBackingImages(&retval);
177     if (!status.isOk()) {
178         LOG(ERROR) << __PRETTY_FUNCTION__
179                    << " binder returned: " << status.exceptionMessage().c_str();
180     }
181     return retval;
182 }
183 
ZeroFillNewImage(const std::string & name,uint64_t bytes)184 FiemapStatus ImageManagerBinder::ZeroFillNewImage(const std::string& name, uint64_t bytes) {
185     auto status = manager_->zeroFillNewImage(name, bytes);
186     return ToFiemapStatus(__PRETTY_FUNCTION__, status);
187 }
188 
RemoveAllImages()189 bool ImageManagerBinder::RemoveAllImages() {
190     auto status = manager_->removeAllImages();
191     if (!status.isOk()) {
192         LOG(ERROR) << __PRETTY_FUNCTION__
193                    << " binder returned: " << status.exceptionMessage().c_str();
194         return false;
195     }
196     return true;
197 }
DisableAllImages()198 bool ImageManagerBinder::DisableAllImages() {
199     return true;
200 }
201 
DisableImage(const std::string & name)202 bool ImageManagerBinder::DisableImage(const std::string& name) {
203     auto status = manager_->disableImage(name);
204     if (!status.isOk()) {
205         LOG(ERROR) << __PRETTY_FUNCTION__
206                    << " binder returned: " << status.exceptionMessage().c_str();
207         return false;
208     }
209     return true;
210 }
211 
RemoveDisabledImages()212 bool ImageManagerBinder::RemoveDisabledImages() {
213     auto status = manager_->removeDisabledImages();
214     if (!status.isOk()) {
215         LOG(ERROR) << __PRETTY_FUNCTION__
216                    << " binder returned: " << status.exceptionMessage().c_str();
217         return false;
218     }
219     return true;
220 }
221 
GetMappedImageDevice(const std::string & name,std::string * device)222 bool ImageManagerBinder::GetMappedImageDevice(const std::string& name, std::string* device) {
223     auto status = manager_->getMappedImageDevice(name, device);
224     if (!status.isOk()) {
225         LOG(ERROR) << __PRETTY_FUNCTION__
226                    << " binder returned: " << status.exceptionMessage().c_str();
227         return false;
228     }
229     return !device->empty();
230 }
231 
IsImageDisabled(const std::string & name)232 bool ImageManagerBinder::IsImageDisabled(const std::string& name) {
233     bool retval;
234     auto status = manager_->isImageDisabled(name, &retval);
235     if (!status.isOk()) {
236         LOG(ERROR) << __PRETTY_FUNCTION__
237                    << " binder returned: " << status.exceptionMessage().c_str();
238         return false;
239     }
240     return retval;
241 }
242 
MapAllImages(const std::function<bool (std::set<std::string>)> &)243 bool ImageManagerBinder::MapAllImages(const std::function<bool(std::set<std::string>)>&) {
244     LOG(ERROR) << __PRETTY_FUNCTION__ << " not available over binder";
245     return false;
246 }
247 
Open(const std::string & dir,const std::chrono::milliseconds &,const DeviceInfo &)248 std::unique_ptr<IImageManager> IImageManager::Open(const std::string& dir,
249                                                    const std::chrono::milliseconds& /*timeout_ms*/,
250                                                    const DeviceInfo&) {
251     android::sp<IGsiService> service = android::gsi::GetGsiService();
252     android::sp<IImageService> manager;
253 
254     auto status = service->openImageService(dir, &manager);
255     if (!status.isOk() || !manager) {
256         LOG(ERROR) << "Could not acquire IImageManager: " << status.exceptionMessage().c_str();
257         return nullptr;
258     }
259     return std::make_unique<ImageManagerBinder>(std::move(service), std::move(manager));
260 }
261 
262 }  // namespace fiemap
263 }  // namespace android
264 
265 #endif  // __ANDROID_RECOVERY__
266