1 // 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 <memory> 18 #include <utility> 19 20 #include <base/files/file_util.h> 21 22 #include <ApexProperties.sysprop.h> 23 24 #include "update_engine/aosp/apex_handler_android.h" 25 26 namespace chromeos_update_engine { 27 28 namespace { 29 CreateCompressedApexInfoList(const std::vector<ApexInfo> & apex_infos)30android::apex::CompressedApexInfoList CreateCompressedApexInfoList( 31 const std::vector<ApexInfo>& apex_infos) { 32 android::apex::CompressedApexInfoList compressed_apex_info_list; 33 for (const auto& apex_info : apex_infos) { 34 if (!apex_info.is_compressed()) { 35 continue; 36 } 37 android::apex::CompressedApexInfo compressed_apex_info; 38 compressed_apex_info.moduleName = apex_info.package_name(); 39 compressed_apex_info.versionCode = apex_info.version(); 40 compressed_apex_info.decompressedSize = apex_info.decompressed_size(); 41 compressed_apex_info_list.apexInfos.emplace_back( 42 std::move(compressed_apex_info)); 43 } 44 return compressed_apex_info_list; 45 } 46 47 } // namespace 48 49 std::unique_ptr<ApexHandlerInterface> CreateApexHandler()50ApexHandlerInterface::CreateApexHandler() { 51 if (android::sysprop::ApexProperties::updatable().value_or(false)) { 52 return std::make_unique<ApexHandlerAndroid>(); 53 } else { 54 return std::make_unique<FlattenedApexHandlerAndroid>(); 55 } 56 } 57 CalculateSize(const std::vector<ApexInfo> & apex_infos) const58android::base::Result<uint64_t> ApexHandlerAndroid::CalculateSize( 59 const std::vector<ApexInfo>& apex_infos) const { 60 // We might not need to decompress every APEX. Communicate with apexd to get 61 // accurate requirement. 62 auto apex_service = GetApexService(); 63 if (apex_service == nullptr) { 64 return android::base::Error() << "Failed to get hold of apexservice"; 65 } 66 67 auto compressed_apex_info_list = CreateCompressedApexInfoList(apex_infos); 68 int64_t size_from_apexd = 0; 69 auto result = apex_service->calculateSizeForCompressedApex( 70 compressed_apex_info_list, &size_from_apexd); 71 if (!result.isOk()) { 72 return android::base::Error() 73 << "Failed to get size required from apexservice"; 74 } 75 return size_from_apexd; 76 } 77 AllocateSpace(const std::vector<ApexInfo> & apex_infos) const78bool ApexHandlerAndroid::AllocateSpace( 79 const std::vector<ApexInfo>& apex_infos) const { 80 auto apex_service = GetApexService(); 81 if (apex_service == nullptr) { 82 return false; 83 } 84 auto compressed_apex_info_list = CreateCompressedApexInfoList(apex_infos); 85 auto result = 86 apex_service->reserveSpaceForCompressedApex(compressed_apex_info_list); 87 return result.isOk(); 88 } 89 GetApexService() const90android::sp<android::apex::IApexService> ApexHandlerAndroid::GetApexService() 91 const { 92 auto binder = android::defaultServiceManager()->waitForService( 93 android::String16("apexservice")); 94 if (binder == nullptr) { 95 return nullptr; 96 } 97 return android::interface_cast<android::apex::IApexService>(binder); 98 } 99 CalculateSize(const std::vector<ApexInfo> & apex_infos) const100android::base::Result<uint64_t> FlattenedApexHandlerAndroid::CalculateSize( 101 const std::vector<ApexInfo>& apex_infos) const { 102 return 0; 103 } 104 AllocateSpace(const std::vector<ApexInfo> & apex_infos) const105bool FlattenedApexHandlerAndroid::AllocateSpace( 106 const std::vector<ApexInfo>& apex_infos) const { 107 return true; 108 } 109 110 } // namespace chromeos_update_engine 111