summaryrefslogtreecommitdiff
path: root/aosp/apex_handler_android.cc
diff options
context:
space:
mode:
Diffstat (limited to 'aosp/apex_handler_android.cc')
-rw-r--r--aosp/apex_handler_android.cc110
1 files changed, 110 insertions, 0 deletions
diff --git a/aosp/apex_handler_android.cc b/aosp/apex_handler_android.cc
new file mode 100644
index 00000000..8beef966
--- /dev/null
+++ b/aosp/apex_handler_android.cc
@@ -0,0 +1,110 @@
+//
+// Copyright (C) 2021 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.
+//
+
+#include <memory>
+#include <utility>
+
+#include <base/files/file_util.h>
+
+#include <ApexProperties.sysprop.h>
+
+#include "update_engine/aosp/apex_handler_android.h"
+#include "update_engine/common/utils.h"
+
+namespace chromeos_update_engine {
+
+namespace {
+
+android::apex::CompressedApexInfoList CreateCompressedApexInfoList(
+ const std::vector<ApexInfo>& apex_infos) {
+ android::apex::CompressedApexInfoList compressed_apex_info_list;
+ for (const auto& apex_info : apex_infos) {
+ if (!apex_info.is_compressed()) {
+ continue;
+ }
+ android::apex::CompressedApexInfo compressed_apex_info;
+ compressed_apex_info.moduleName = apex_info.package_name();
+ compressed_apex_info.versionCode = apex_info.version();
+ compressed_apex_info.decompressedSize = apex_info.decompressed_size();
+ compressed_apex_info_list.apexInfos.emplace_back(
+ std::move(compressed_apex_info));
+ }
+ return compressed_apex_info_list;
+}
+
+} // namespace
+
+std::unique_ptr<ApexHandlerInterface> CreateApexHandler() {
+ if (android::sysprop::ApexProperties::updatable().value_or(false)) {
+ return std::make_unique<ApexHandlerAndroid>();
+ } else {
+ return std::make_unique<FlattenedApexHandlerAndroid>();
+ }
+}
+
+android::base::Result<uint64_t> ApexHandlerAndroid::CalculateSize(
+ const std::vector<ApexInfo>& apex_infos) const {
+ // We might not need to decompress every APEX. Communicate with apexd to get
+ // accurate requirement.
+ auto apex_service = GetApexService();
+ if (apex_service == nullptr) {
+ return android::base::Error() << "Failed to get hold of apexservice";
+ }
+
+ auto compressed_apex_info_list = CreateCompressedApexInfoList(apex_infos);
+ int64_t size_from_apexd;
+ auto result = apex_service->calculateSizeForCompressedApex(
+ compressed_apex_info_list, &size_from_apexd);
+ if (!result.isOk()) {
+ return android::base::Error()
+ << "Failed to get size required from apexservice";
+ }
+ return size_from_apexd;
+}
+
+bool ApexHandlerAndroid::AllocateSpace(
+ const std::vector<ApexInfo>& apex_infos) const {
+ auto apex_service = GetApexService();
+ if (apex_service == nullptr) {
+ return false;
+ }
+ auto compressed_apex_info_list = CreateCompressedApexInfoList(apex_infos);
+ auto result =
+ apex_service->reserveSpaceForCompressedApex(compressed_apex_info_list);
+ return result.isOk();
+}
+
+android::sp<android::apex::IApexService> ApexHandlerAndroid::GetApexService()
+ const {
+ auto binder = android::defaultServiceManager()->waitForService(
+ android::String16("apexservice"));
+ if (binder == nullptr) {
+ return nullptr;
+ }
+ return android::interface_cast<android::apex::IApexService>(binder);
+}
+
+android::base::Result<uint64_t> FlattenedApexHandlerAndroid::CalculateSize(
+ const std::vector<ApexInfo>& apex_infos) const {
+ return 0;
+}
+
+bool FlattenedApexHandlerAndroid::AllocateSpace(
+ const std::vector<ApexInfo>& apex_infos) const {
+ return true;
+}
+
+} // namespace chromeos_update_engine