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.cc98
1 files changed, 98 insertions, 0 deletions
diff --git a/aosp/apex_handler_android.cc b/aosp/apex_handler_android.cc
new file mode 100644
index 00000000..cdbc9834
--- /dev/null
+++ b/aosp/apex_handler_android.cc
@@ -0,0 +1,98 @@
+//
+// 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 <utility>
+
+#include <base/files/file_util.h>
+
+#include "update_engine/aosp/apex_handler_android.h"
+#include "update_engine/common/utils.h"
+
+namespace chromeos_update_engine {
+
+// Don't change this path... apexd relies on it.
+constexpr const char* kApexReserveSpaceDir = "/data/apex/ota_reserved";
+
+uint64_t ApexHandlerAndroid::CalculateSize(
+ const std::vector<ApexInfo>& apex_infos) const {
+ return CalculateSize(apex_infos, GetApexService());
+}
+
+uint64_t ApexHandlerAndroid::CalculateSize(
+ const std::vector<ApexInfo>& apex_infos,
+ android::sp<android::apex::IApexService> apex_service) const {
+ // The safest option is to allocate space for every compressed APEX
+ uint64_t size_required_default = 0;
+
+ // We might not need to decompress every APEX. Communicate with apexd to get
+ // accurate requirement.
+ int64_t size_from_apexd;
+ android::apex::CompressedApexInfoList compressed_apex_info_list;
+
+ for (const auto& apex_info : apex_infos) {
+ if (!apex_info.is_compressed()) {
+ continue;
+ }
+
+ size_required_default += apex_info.decompressed_size();
+
+ 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));
+ }
+ if (size_required_default == 0 || apex_service == nullptr) {
+ return size_required_default;
+ }
+
+ auto result = apex_service->calculateSizeForCompressedApex(
+ compressed_apex_info_list, &size_from_apexd);
+ if (!result.isOk()) {
+ return size_required_default;
+ }
+ return size_from_apexd;
+}
+
+bool ApexHandlerAndroid::AllocateSpace(const uint64_t size_required) const {
+ return AllocateSpace(size_required, kApexReserveSpaceDir);
+}
+
+bool ApexHandlerAndroid::AllocateSpace(const uint64_t size_required,
+ const std::string& dir_path) const {
+ if (size_required == 0) {
+ return true;
+ }
+ base::FilePath path{dir_path};
+ // The filename is not important, it just needs to be under
+ // kApexReserveSpaceDir. We call it "full.tmp" because the current space
+ // estimation is simply adding up all decompressed sizes.
+ path = path.Append("full.tmp");
+ return utils::ReserveStorageSpace(path.value().c_str(), size_required);
+}
+
+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);
+}
+
+} // namespace chromeos_update_engine