blob: cdbc9834e4b0810841c591e308f07b184485c074 [file] [log] [blame]
Mohammad Samiul Islam24a82792021-02-12 16:52:36 +00001//
2// Copyright (C) 2021 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#include <utility>
18
19#include <base/files/file_util.h>
20
21#include "update_engine/aosp/apex_handler_android.h"
22#include "update_engine/common/utils.h"
23
24namespace chromeos_update_engine {
25
26// Don't change this path... apexd relies on it.
27constexpr const char* kApexReserveSpaceDir = "/data/apex/ota_reserved";
28
29uint64_t ApexHandlerAndroid::CalculateSize(
30 const std::vector<ApexInfo>& apex_infos) const {
31 return CalculateSize(apex_infos, GetApexService());
32}
33
34uint64_t ApexHandlerAndroid::CalculateSize(
35 const std::vector<ApexInfo>& apex_infos,
36 android::sp<android::apex::IApexService> apex_service) const {
37 // The safest option is to allocate space for every compressed APEX
38 uint64_t size_required_default = 0;
39
40 // We might not need to decompress every APEX. Communicate with apexd to get
41 // accurate requirement.
42 int64_t size_from_apexd;
43 android::apex::CompressedApexInfoList compressed_apex_info_list;
44
45 for (const auto& apex_info : apex_infos) {
46 if (!apex_info.is_compressed()) {
47 continue;
48 }
49
50 size_required_default += apex_info.decompressed_size();
51
52 android::apex::CompressedApexInfo compressed_apex_info;
53 compressed_apex_info.moduleName = apex_info.package_name();
54 compressed_apex_info.versionCode = apex_info.version();
55 compressed_apex_info.decompressedSize = apex_info.decompressed_size();
56 compressed_apex_info_list.apexInfos.emplace_back(
57 std::move(compressed_apex_info));
58 }
59 if (size_required_default == 0 || apex_service == nullptr) {
60 return size_required_default;
61 }
62
63 auto result = apex_service->calculateSizeForCompressedApex(
64 compressed_apex_info_list, &size_from_apexd);
65 if (!result.isOk()) {
66 return size_required_default;
67 }
68 return size_from_apexd;
69}
70
71bool ApexHandlerAndroid::AllocateSpace(const uint64_t size_required) const {
72 return AllocateSpace(size_required, kApexReserveSpaceDir);
73}
74
75bool ApexHandlerAndroid::AllocateSpace(const uint64_t size_required,
76 const std::string& dir_path) const {
77 if (size_required == 0) {
78 return true;
79 }
80 base::FilePath path{dir_path};
81 // The filename is not important, it just needs to be under
82 // kApexReserveSpaceDir. We call it "full.tmp" because the current space
83 // estimation is simply adding up all decompressed sizes.
84 path = path.Append("full.tmp");
85 return utils::ReserveStorageSpace(path.value().c_str(), size_required);
86}
87
88android::sp<android::apex::IApexService> ApexHandlerAndroid::GetApexService()
89 const {
90 auto binder = android::defaultServiceManager()->waitForService(
91 android::String16("apexservice"));
92 if (binder == nullptr) {
93 return nullptr;
94 }
95 return android::interface_cast<android::apex::IApexService>(binder);
96}
97
98} // namespace chromeos_update_engine