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 #include "update_engine/common/utils.h" 26 27 namespace chromeos_update_engine { 28 29 namespace { 30 CreateCompressedApexInfoList(const std::vector<ApexInfo> & apex_infos)31android::apex::CompressedApexInfoList CreateCompressedApexInfoList( 32 const std::vector<ApexInfo>& apex_infos) { 33 android::apex::CompressedApexInfoList compressed_apex_info_list; 34 for (const auto& apex_info : apex_infos) { 35 if (!apex_info.is_compressed()) { 36 continue; 37 } 38 android::apex::CompressedApexInfo compressed_apex_info; 39 compressed_apex_info.moduleName = apex_info.package_name(); 40 compressed_apex_info.versionCode = apex_info.version(); 41 compressed_apex_info.decompressedSize = apex_info.decompressed_size(); 42 compressed_apex_info_list.apexInfos.emplace_back( 43 std::move(compressed_apex_info)); 44 } 45 return compressed_apex_info_list; 46 } 47 48 } // namespace 49 CreateApexHandler()50std::unique_ptr<ApexHandlerInterface> 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; 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