From d66695bf344a42b20ddef77631449f062b8ae5c9 Mon Sep 17 00:00:00 2001 From: Yifan Hong Date: Mon, 23 Dec 2019 16:07:45 -0800 Subject: ImageManager returns FiemapStatus. IImageManager::CreateBackingImage and ZeroFillNewImage now returns FiemapStatus, which indicates the source of error. Put the error code in binder::Status object as service specific error. Test: libsnapshot_test Bug: 138808058 Change-Id: I8b93c05ac7cceeb500e98945b16e43d5fde2cc4c --- Android.bp | 1 + aidl/android/gsi/IImageService.aidl | 15 ++++++++++---- aidl/android/gsi/IProgressCallback.aidl | 34 +++++++++++++++++++++++++++++++ gsi_service.cpp | 36 ++++++++++++++++++++++++--------- 4 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 aidl/android/gsi/IProgressCallback.aidl diff --git a/Android.bp b/Android.bp index f911851..5b7b8d9 100644 --- a/Android.bp +++ b/Android.bp @@ -125,6 +125,7 @@ filegroup { "aidl/android/gsi/IImageService.aidl", "aidl/android/gsi/IGsid.aidl", "aidl/android/gsi/IGsiService.aidl", + "aidl/android/gsi/IProgressCallback.aidl", "aidl/android/gsi/MappedImage.aidl", ], path: "aidl", diff --git a/aidl/android/gsi/IImageService.aidl b/aidl/android/gsi/IImageService.aidl index d991874..5d9002f 100644 --- a/aidl/android/gsi/IImageService.aidl +++ b/aidl/android/gsi/IImageService.aidl @@ -17,6 +17,7 @@ package android.gsi; import android.gsi.MappedImage; +import android.gsi.IProgressCallback; /** {@hide} */ interface IImageService { @@ -35,15 +36,20 @@ interface IImageService { * free, the call will fail. * @param readonly If readonly, MapBackingImage() will configure the device as * readonly. - * @return True on success, false otherwise. + * @param on_progress Progress callback. It is invoked when there is an interesting update. + * For each invocation, |current| is the number of bytes actually written, + * and |total| is set to |size|. + * @throws ServiceSpecificException if any error occurs. Exception code is a + * FiemapStatus::ErrorCode value. */ - void createBackingImage(@utf8InCpp String name, long size, int flags); + void createBackingImage(@utf8InCpp String name, long size, int flags, + @nullable IProgressCallback on_progress); /** * Delete an image created with createBackingImage. * * @param name Image name as passed to createBackingImage(). - * @return True on success, false otherwise. + * @throws ServiceSpecificException if any error occurs. */ void deleteBackingImage(@utf8InCpp String name); @@ -95,7 +101,8 @@ interface IImageService { * @param bytes Number of zeros to be written, starting from the * beginning. If bytes is equal to 0, then the whole * image file is filled with zeros. - * @return True on success, false otherwise. + * @throws ServiceSpecificException if any error occurs. Exception code is a + * FiemapStatus::ErrorCode value. */ void zeroFillNewImage(@utf8InCpp String name, long bytes); diff --git a/aidl/android/gsi/IProgressCallback.aidl b/aidl/android/gsi/IProgressCallback.aidl new file mode 100644 index 0000000..b7acefc --- /dev/null +++ b/aidl/android/gsi/IProgressCallback.aidl @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.gsi; + +/** {@hide} */ +interface IProgressCallback { + /** + * Report progress for a long-running task. + * + * The percentage can be computed using current / total. The task is + * done when current == total. + * + * Different APIs may have different meanings for the parameters; see + * specific APIs for details. + * + * @param current a value indicating the current progress. Should be treated as uint64. + * @param total a value indicating 100% progress. Should be treated as uint64. + */ + void onProgress(long current, long total); +} diff --git a/gsi_service.cpp b/gsi_service.cpp index bfe6bf4..f3665f9 100644 --- a/gsi_service.cpp +++ b/gsi_service.cpp @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -369,9 +370,9 @@ binder::Status GsiService::zeroPartition(const std::string& name, int* _aidl_ret return binder::Status::ok(); } -static binder::Status BinderError(const std::string& message) { - return binder::Status::fromExceptionCode(binder::Status::EX_SERVICE_SPECIFIC, - String8(message.c_str())); +static binder::Status BinderError(const std::string& message, + FiemapStatus::ErrorCode status = FiemapStatus::ErrorCode::ERROR) { + return binder::Status::fromServiceSpecificError(static_cast(status), message.c_str()); } binder::Status GsiService::dumpDeviceMapperDevices(std::string* _aidl_return) { @@ -440,7 +441,8 @@ class ImageService : public BinderService, public BnImageService { public: ImageService(GsiService* service, std::unique_ptr&& impl, uid_t uid); binder::Status getAllBackingImages(std::vector* _aidl_return); - binder::Status createBackingImage(const std::string& name, int64_t size, int flags) override; + binder::Status createBackingImage(const std::string& name, int64_t size, int flags, + const sp& on_progress) override; binder::Status deleteBackingImage(const std::string& name) override; binder::Status mapImageDevice(const std::string& name, int32_t timeout_ms, MappedImage* mapping) override; @@ -469,13 +471,28 @@ binder::Status ImageService::getAllBackingImages(std::vector* _aidl return binder::Status::ok(); } -binder::Status ImageService::createBackingImage(const std::string& name, int64_t size, int flags) { +binder::Status ImageService::createBackingImage(const std::string& name, int64_t size, int flags, + const sp& on_progress) { if (!CheckUid()) return UidSecurityError(); std::lock_guard guard(parent_->lock()); - if (!impl_->CreateBackingImage(name, size, flags, nullptr)) { - return BinderError("Failed to create"); + std::function callback; + if (on_progress) { + callback = [on_progress](uint64_t current, uint64_t total) -> bool { + auto status = on_progress->onProgress(static_cast(current), + static_cast(total)); + if (!status.isOk()) { + LOG(ERROR) << "progress callback returned: " << status.toString8().string(); + return false; + } + return true; + }; + } + + auto res = impl_->CreateBackingImage(name, size, flags, std::move(callback)); + if (!res.is_ok()) { + return BinderError("Failed to create: " + res.string(), res.error_code()); } return binder::Status::ok(); } @@ -540,8 +557,9 @@ binder::Status ImageService::zeroFillNewImage(const std::string& name, int64_t b if (bytes < 0) { return BinderError("Cannot use negative values"); } - if (!impl_->ZeroFillNewImage(name, bytes)) { - return BinderError("Failed to fill image with zeros"); + auto res = impl_->ZeroFillNewImage(name, bytes); + if (!res.is_ok()) { + return BinderError("Failed to fill image with zeros: " + res.string(), res.error_code()); } return binder::Status::ok(); } -- cgit v1.2.3