1 2 /* 3 * Copyright (C) 2024 The Android Open Source Project 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 #include "storage_files_manager.h" 19 20 #include <android-base/logging.h> 21 22 #include "aconfigd.h" 23 #include "aconfigd_util.h" 24 #include "com_android_aconfig_new_storage.h" 25 26 using namespace aconfig_storage; 27 28 namespace android { 29 namespace aconfigd { 30 31 /// get storage files object for a container GetStorageFiles(const std::string & container)32 base::Result<StorageFiles*> StorageFilesManager::GetStorageFiles( 33 const std::string& container) { 34 if (all_storage_files_.count(container) == 0) { 35 return base::Error() << "Missing storage files object for " << container; 36 } 37 return all_storage_files_[container].get(); 38 } 39 40 /// create mapped files for a container AddNewStorageFiles(const std::string & container,const std::string & package_map,const std::string & flag_map,const std::string & flag_val,const std::string & flag_info)41 base::Result<StorageFiles*> StorageFilesManager::AddNewStorageFiles( 42 const std::string& container, 43 const std::string& package_map, 44 const std::string& flag_map, 45 const std::string& flag_val, 46 const std::string& flag_info) { 47 if (all_storage_files_.count(container)) { 48 return base::Error() << "Storage file object for " << container << " already exists"; 49 } 50 51 auto result = base::Result<void>({}); 52 auto storage_files = std::make_unique<StorageFiles>( 53 container, package_map, flag_map, flag_val, flag_info, root_dir_, result); 54 55 if (!result.ok()) { 56 return base::Error() << "Failed to create storage file object for " << container 57 << ": " << result.error(); 58 } 59 60 auto storage_files_ptr = storage_files.get(); 61 all_storage_files_[container].reset(storage_files.release()); 62 return storage_files_ptr; 63 } 64 65 /// restore storage files object from a storage record pb entry RestoreStorageFiles(const PersistStorageRecord & pb)66 base::Result<void> StorageFilesManager::RestoreStorageFiles( 67 const PersistStorageRecord& pb) { 68 if (all_storage_files_.count(pb.container())) { 69 return base::Error() << "Storage file object for " << pb.container() 70 << " already exists"; 71 } 72 73 all_storage_files_[pb.container()] = std::make_unique<StorageFiles>(pb, root_dir_); 74 return {}; 75 } 76 77 /// update existing storage files object with new storage file set UpdateStorageFiles(const std::string & container,const std::string & package_map,const std::string & flag_map,const std::string & flag_val,const std::string & flag_info)78 base::Result<void> StorageFilesManager::UpdateStorageFiles( 79 const std::string& container, 80 const std::string& package_map, 81 const std::string& flag_map, 82 const std::string& flag_val, 83 const std::string& flag_info) { 84 if (!all_storage_files_.count(container)) { 85 return base::Error() << "Failed to update storage files object for " << container 86 << ", it does not exist"; 87 } 88 89 // backup server and local override 90 auto storage_files = GetStorageFiles(container); 91 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 92 auto server_overrides = (**storage_files).GetServerFlagValues(); 93 RETURN_IF_ERROR(server_overrides, "Failed to get existing server overrides"); 94 95 auto pb_file = (**storage_files).GetStorageRecord().local_overrides; 96 auto local_overrides = ReadPbFromFile<LocalFlagOverrides>(pb_file); 97 RETURN_IF_ERROR(local_overrides, "Failed to read local overrides from " + pb_file); 98 99 // clean up existing storage files object and recreate 100 (**storage_files).RemoveAllPersistFiles(); 101 all_storage_files_.erase(container); 102 storage_files = AddNewStorageFiles( 103 container, package_map, flag_map, flag_val, flag_info); 104 RETURN_IF_ERROR(storage_files, "Failed to add a new storage object for " + container); 105 106 // reapply local overrides 107 auto updated_local_overrides = LocalFlagOverrides(); 108 for (const auto& entry : local_overrides->overrides()) { 109 auto has_flag = (**storage_files).HasFlag(entry.package_name(), entry.flag_name()); 110 RETURN_IF_ERROR(has_flag, "Failed to check if has flag for " + entry.package_name() 111 + "/" + entry.flag_name()); 112 if (*has_flag) { 113 auto context = (**storage_files).GetPackageFlagContext( 114 entry.package_name(), entry.flag_name()); 115 RETURN_IF_ERROR(context, "Failed to find package flag context for " + 116 entry.package_name() + "/" + entry.flag_name()); 117 118 auto update = (**storage_files).SetHasLocalOverride(*context, true); 119 RETURN_IF_ERROR(update, "Failed to set flag has local override"); 120 121 auto* new_override = updated_local_overrides.add_overrides(); 122 new_override->set_package_name(entry.package_name()); 123 new_override->set_flag_name(entry.flag_name()); 124 new_override->set_flag_value(entry.flag_value()); 125 } 126 } 127 auto result = WritePbToFile<LocalFlagOverrides>(updated_local_overrides, pb_file); 128 129 // reapply server overrides 130 for (const auto& entry : *server_overrides) { 131 auto has_flag = (**storage_files).HasFlag(entry.package_name, entry.flag_name); 132 RETURN_IF_ERROR(has_flag, "Failed to check if has flag for " + entry.package_name 133 + "/" + entry.flag_name); 134 if (*has_flag) { 135 auto context = (**storage_files).GetPackageFlagContext( 136 entry.package_name, entry.flag_name); 137 RETURN_IF_ERROR(context, "Failed to find package flag context for " + 138 entry.package_name + "/" + entry.flag_name); 139 140 auto update = (**storage_files).SetServerFlagValue(*context, entry.flag_value); 141 RETURN_IF_ERROR(update, "Failed to set server flag value"); 142 } 143 } 144 145 return {}; 146 } 147 148 /// add or update storage file set for a container AddOrUpdateStorageFiles(const std::string & container,const std::string & package_map,const std::string & flag_map,const std::string & flag_val,const std::string & flag_info)149 base::Result<bool> StorageFilesManager::AddOrUpdateStorageFiles( 150 const std::string& container, 151 const std::string& package_map, 152 const std::string& flag_map, 153 const std::string& flag_val, 154 const std::string& flag_info) { 155 bool new_container = !HasContainer(container); 156 bool update_existing_container = false; 157 if (!new_container) { 158 auto digest = GetFilesDigest({package_map, flag_map, flag_val, flag_info}); 159 RETURN_IF_ERROR(digest, "Failed to get digest for " + container); 160 auto storage_files = GetStorageFiles(container); 161 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 162 if ((**storage_files).GetStorageRecord().digest != *digest) { 163 update_existing_container = true; 164 } 165 } 166 167 // early return if no update is needed 168 if (!(new_container || update_existing_container)) { 169 return false; 170 } 171 172 if (new_container) { 173 auto storage_files = AddNewStorageFiles( 174 container, package_map, flag_map, flag_val, flag_info); 175 RETURN_IF_ERROR(storage_files, "Failed to add a new storage object for " + container); 176 } else { 177 auto storage_files = UpdateStorageFiles( 178 container, package_map, flag_map, flag_val, flag_info); 179 RETURN_IF_ERROR(storage_files, "Failed to update storage object for " + container); 180 } 181 182 return true; 183 } 184 185 /// create boot copy CreateStorageBootCopy(const std::string & container)186 base::Result<void> StorageFilesManager::CreateStorageBootCopy( 187 const std::string& container) { 188 if (!HasContainer(container)) { 189 return base::Error() << "Cannot create boot copy without persist copy for " << container; 190 } 191 auto storage_files = GetStorageFiles(container); 192 auto copy_result = (**storage_files).CreateBootStorageFiles(); 193 RETURN_IF_ERROR(copy_result, "Failed to create boot copies for " + container); 194 return {}; 195 } 196 197 /// reset all storage ResetAllStorage()198 base::Result<void> StorageFilesManager::ResetAllStorage() { 199 for (const auto& container : GetAllContainers()) { 200 auto storage_files = GetStorageFiles(container); 201 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 202 bool available = (**storage_files).HasBootCopy(); 203 StorageRecord record = (**storage_files).GetStorageRecord(); 204 205 (**storage_files).RemoveAllPersistFiles(); 206 all_storage_files_.erase(container); 207 208 if (available) { 209 auto storage_files = AddNewStorageFiles( 210 container, record.package_map, record.flag_map, record.flag_val, record.flag_info); 211 RETURN_IF_ERROR(storage_files, "Failed to add a new storage object for " + container); 212 } 213 } 214 return {}; 215 } 216 217 /// get container name given flag package name GetContainer(const std::string & package)218 base::Result<std::string> StorageFilesManager::GetContainer( 219 const std::string& package) { 220 if (package_to_container_.count(package)) { 221 return package_to_container_[package]; 222 } 223 224 for (const auto& [container, storage_files] : all_storage_files_) { 225 auto has_flag = storage_files->HasPackage(package); 226 RETURN_IF_ERROR(has_flag, "Failed to check if has flag"); 227 228 if (*has_flag) { 229 package_to_container_[package] = container; 230 return container; 231 } 232 } 233 234 return base::Error() << "container not found"; 235 } 236 237 /// Get all storage records GetAllStorageRecords()238 std::vector<const StorageRecord*> StorageFilesManager::GetAllStorageRecords() { 239 auto all_records = std::vector<const StorageRecord*>(); 240 for (auto const& [container, files_ptr] : all_storage_files_) { 241 all_records.push_back(&(files_ptr->GetStorageRecord())); 242 } 243 return all_records; 244 } 245 246 /// get all containers GetAllContainers()247 std::vector<std::string> StorageFilesManager::GetAllContainers() { 248 auto containers = std::vector<std::string>(); 249 for (const auto& item : all_storage_files_) { 250 containers.push_back(item.first); 251 } 252 return containers; 253 } 254 255 /// write to persist storage records pb file WritePersistStorageRecordsToFile(const std::string & file_name)256 base::Result<void> StorageFilesManager::WritePersistStorageRecordsToFile( 257 const std::string& file_name) { 258 auto records_pb = PersistStorageRecords(); 259 for (const auto& [container, storage_files] : all_storage_files_) { 260 const auto& record = storage_files->GetStorageRecord(); 261 auto* record_pb = records_pb.add_records(); 262 record_pb->set_version(record.version); 263 record_pb->set_container(record.container); 264 record_pb->set_package_map(record.package_map); 265 record_pb->set_flag_map(record.flag_map); 266 record_pb->set_flag_val(record.flag_val); 267 record_pb->set_flag_info(record.flag_info); 268 record_pb->set_digest(record.digest); 269 } 270 return WritePbToFile<PersistStorageRecords>(records_pb, file_name); 271 } 272 273 /// apply flag override UpdateFlagValue(const std::string & package_name,const std::string & flag_name,const std::string & flag_value,const StorageRequestMessage::FlagOverrideType override_type)274 base::Result<void> StorageFilesManager::UpdateFlagValue( 275 const std::string& package_name, const std::string& flag_name, 276 const std::string& flag_value, 277 const StorageRequestMessage::FlagOverrideType override_type) { 278 auto container = GetContainer(package_name); 279 RETURN_IF_ERROR(container, "Failed to find owning container"); 280 281 auto storage_files = GetStorageFiles(*container); 282 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 283 284 auto context = (**storage_files).GetPackageFlagContext(package_name, flag_name); 285 RETURN_IF_ERROR(context, "Failed to find package flag context"); 286 287 switch (override_type) { 288 case StorageRequestMessage::LOCAL_ON_REBOOT: { 289 auto update = (**storage_files).SetLocalFlagValue(*context, flag_value); 290 RETURN_IF_ERROR(update, "Failed to set local flag override"); 291 break; 292 } 293 case StorageRequestMessage::SERVER_ON_REBOOT: { 294 auto update = 295 (**storage_files).SetServerFlagValue(*context, flag_value); 296 RETURN_IF_ERROR(update, "Failed to set server flag value"); 297 break; 298 } 299 case StorageRequestMessage::LOCAL_IMMEDIATE: { 300 auto updateOverride = 301 (**storage_files).SetLocalFlagValue(*context, flag_value); 302 RETURN_IF_ERROR(updateOverride, "Failed to set local flag override"); 303 auto updateBootFile = 304 (**storage_files) 305 .UpdateBootValueAndInfoImmediately(*context, flag_value, true); 306 RETURN_IF_ERROR(updateBootFile, 307 "Failed to write local override to boot file"); 308 break; 309 } 310 default: 311 return base::Error() << "unknown flag override type"; 312 } 313 314 return {}; 315 } 316 317 /// apply ota flags and return remaining ota flags ApplyOTAFlagsForContainer(const std::string & container,const std::vector<FlagOverride> & ota_flags)318 base::Result<std::vector<FlagOverride>> StorageFilesManager::ApplyOTAFlagsForContainer( 319 const std::string& container, 320 const std::vector<FlagOverride>& ota_flags) { 321 auto storage_files = GetStorageFiles(container); 322 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 323 324 auto remaining_ota_flags = std::vector<FlagOverride>(); 325 for (const auto& entry : ota_flags) { 326 auto has_flag = (**storage_files).HasPackage(entry.package_name()); 327 RETURN_IF_ERROR(has_flag, "Failed to check if has flag"); 328 if (*has_flag) { 329 auto result = UpdateFlagValue(entry.package_name(), 330 entry.flag_name(), 331 entry.flag_value()); 332 if (!result.ok()) { 333 LOG(ERROR) << "Failed to apply staged OTA flag " << entry.package_name() 334 << "/" << entry.flag_name() << ": " << result.error(); 335 } 336 } else { 337 remaining_ota_flags.push_back(entry); 338 } 339 } 340 341 return remaining_ota_flags; 342 } 343 344 /// remove all local overrides RemoveAllLocalOverrides(const StorageRequestMessage::RemoveOverrideType remove_override_type)345 base::Result<void> StorageFilesManager::RemoveAllLocalOverrides( 346 const StorageRequestMessage::RemoveOverrideType remove_override_type) { 347 for (const auto& [container, storage_files] : all_storage_files_) { 348 bool immediate = 349 remove_override_type == StorageRequestMessage::REMOVE_LOCAL_IMMEDIATE; 350 auto update = storage_files->RemoveAllLocalFlagValue(immediate); 351 RETURN_IF_ERROR(update, "Failed to remove local overrides for " + container); 352 } 353 return {}; 354 } 355 356 /// remove a local override RemoveFlagLocalOverride(const std::string & package,const std::string & flag,const StorageRequestMessage::RemoveOverrideType remove_override_type)357 base::Result<void> StorageFilesManager::RemoveFlagLocalOverride( 358 const std::string& package, const std::string& flag, 359 const StorageRequestMessage::RemoveOverrideType remove_override_type) { 360 auto container = GetContainer(package); 361 RETURN_IF_ERROR(container, "Failed to find owning container"); 362 363 auto storage_files = GetStorageFiles(*container); 364 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 365 366 auto context = (**storage_files).GetPackageFlagContext(package, flag); 367 RETURN_IF_ERROR(context, "Failed to find package flag context"); 368 369 bool immediate = 370 remove_override_type == StorageRequestMessage::REMOVE_LOCAL_IMMEDIATE; 371 auto removed = (**storage_files).RemoveLocalFlagValue(*context, immediate); 372 RETURN_IF_ERROR(removed, "Failed to remove local override"); 373 374 return {}; 375 } 376 377 /// list a flag ListFlag(const std::string & package,const std::string & flag)378 base::Result<StorageFiles::FlagSnapshot> StorageFilesManager::ListFlag( 379 const std::string& package, 380 const std::string& flag) { 381 auto container = GetContainer(package); 382 RETURN_IF_ERROR(container, "Failed to find owning container"); 383 auto storage_files = GetStorageFiles(*container); 384 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 385 386 if ((**storage_files).HasBootCopy()) { 387 return (**storage_files).ListFlag(package, flag); 388 } else{ 389 return base::Error() << "Container " << *container << " is currently unavailable"; 390 } 391 } 392 393 /// list flags in a package 394 base::Result<std::vector<StorageFiles::FlagSnapshot>> ListFlagsInPackage(const std::string & package)395 StorageFilesManager::ListFlagsInPackage(const std::string& package) { 396 auto container = GetContainer(package); 397 RETURN_IF_ERROR(container, "Failed to find owning container for " + package); 398 auto storage_files = GetStorageFiles(*container); 399 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 400 401 if ((**storage_files).HasBootCopy()) { 402 return (**storage_files).ListFlags(package); 403 } else{ 404 return base::Error() << "Container " << *container << " is currently unavailable"; 405 } 406 } 407 408 /// list flags in a container 409 base::Result<std::vector<StorageFiles::FlagSnapshot>> ListFlagsInContainer(const std::string & container)410 StorageFilesManager::ListFlagsInContainer(const std::string& container) { 411 auto storage_files = GetStorageFiles(container); 412 RETURN_IF_ERROR(storage_files, "Failed to get storage files object"); 413 414 if ((**storage_files).HasBootCopy()) { 415 return (**storage_files).ListFlags(); 416 } else { 417 return base::Error() << "Container " << container << " is currently unavailable"; 418 } 419 } 420 421 /// list all available flags 422 base::Result<std::vector<StorageFiles::FlagSnapshot>> ListAllAvailableFlags()423 StorageFilesManager::ListAllAvailableFlags() { 424 auto total_flags = std::vector<StorageFiles::FlagSnapshot>(); 425 for (const auto& [container, storage_files] : all_storage_files_) { 426 if (!storage_files->HasBootCopy()) { 427 continue; 428 } 429 auto flags = storage_files->ListFlags(); 430 RETURN_IF_ERROR(flags, "Failed to list flags in " + container); 431 total_flags.reserve(total_flags.size() + flags->size()); 432 total_flags.insert(total_flags.end(), flags->begin(), flags->end()); 433 } 434 return total_flags; 435 } 436 437 } // namespace aconfigd 438 } // namespace android 439