1 /* 2 * Copyright (C) 2024 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 <android-base/logging.h> 18 #include <unistd.h> 19 20 #include <aconfig_storage/aconfig_storage_file.hpp> 21 22 #include "aconfigd.h" 23 #include "aconfigd_util.h" 24 #include "storage_files.h" 25 26 using namespace aconfig_storage; 27 28 namespace android { 29 namespace aconfigd { 30 31 /// constructor for a new storage file set StorageFiles(const std::string & container,const std::string & package_map,const std::string & flag_map,const std::string & flag_val,const std::string & root_dir,base::Result<void> & status)32 StorageFiles::StorageFiles(const std::string& container, 33 const std::string& package_map, 34 const std::string& flag_map, 35 const std::string& flag_val, 36 const std::string& root_dir, 37 base::Result<void>& status) 38 : container_(container) 39 , storage_record_() 40 , package_map_(nullptr) 41 , flag_map_(nullptr) 42 , flag_val_(nullptr) 43 , boot_flag_val_(nullptr) 44 , boot_flag_info_(nullptr) 45 , persist_flag_val_(nullptr) 46 , persist_flag_info_(nullptr) { 47 auto version = get_storage_file_version(flag_val); 48 if (!version.ok()) { 49 status = base::Error() << "failed to get file version: " << version.error(); 50 return; 51 } 52 53 auto digest = GetFilesDigest({package_map, flag_map, flag_val}); 54 if (!digest.ok()) { 55 status = base::Error() << "failed to get files digest: " << digest.error(); 56 return; 57 } 58 59 storage_record_.version = *version; 60 storage_record_.container = container; 61 storage_record_.package_map = package_map; 62 storage_record_.flag_map = flag_map; 63 storage_record_.flag_val = flag_val; 64 storage_record_.persist_package_map = 65 root_dir + "/maps/" + container + ".package.map"; 66 storage_record_.persist_flag_map = 67 root_dir + "/maps/" + container + ".flag.map"; 68 storage_record_.persist_flag_val = 69 root_dir + "/flags/" + container + ".val"; 70 storage_record_.persist_flag_info = 71 root_dir + "/flags/" + container + ".info"; 72 storage_record_.local_overrides = 73 root_dir + "/flags/" + container + "_local_overrides.pb"; 74 storage_record_.boot_flag_val = 75 root_dir + "/boot/" + container + ".val"; 76 storage_record_.boot_flag_info = 77 root_dir + "/boot/" + container + ".info"; 78 storage_record_.digest= *digest; 79 80 // copy package map file 81 auto copy_result = CopyFile(package_map, storage_record_.persist_package_map, 0444); 82 if (!copy_result.ok()) { 83 status = base::Error() << "CopyFile failed for " << package_map << ": " 84 << copy_result.error(); 85 return; 86 } 87 88 // copy flag map file 89 copy_result = CopyFile(flag_map, storage_record_.persist_flag_map, 0444); 90 if (!copy_result.ok()) { 91 status = base::Error() << "CopyFile failed for " << flag_map << ": " 92 << copy_result.error(); 93 return; 94 } 95 96 // copy flag value file 97 copy_result = CopyFile(flag_val, storage_record_.persist_flag_val, 0644); 98 if (!copy_result.ok()) { 99 status = base::Error() << "CopyFile failed for " << flag_val << ": " 100 << copy_result.error(); 101 return; 102 } 103 104 // create flag info file 105 auto create_result = create_flag_info( 106 package_map, flag_map, storage_record_.persist_flag_info); 107 if (!create_result.ok()) { 108 status = base::Error() << "failed to create flag info file for " << container 109 << create_result.error(); 110 return; 111 } 112 } 113 114 /// constructor for existing new storage file set StorageFiles(const PersistStorageRecord & pb,const std::string & root_dir)115 StorageFiles::StorageFiles(const PersistStorageRecord& pb, 116 const std::string& root_dir) 117 : container_(pb.container()) 118 , storage_record_() 119 , package_map_(nullptr) 120 , flag_map_(nullptr) 121 , flag_val_(nullptr) 122 , boot_flag_val_(nullptr) 123 , boot_flag_info_(nullptr) 124 , persist_flag_val_(nullptr) 125 , persist_flag_info_(nullptr) { 126 storage_record_.version = pb.version(); 127 storage_record_.container = pb.container(); 128 storage_record_.package_map = pb.package_map(); 129 storage_record_.flag_map = pb.flag_map(); 130 storage_record_.flag_val = pb.flag_val(); 131 storage_record_.persist_package_map = 132 root_dir + "/maps/" + pb.container() + ".package.map"; 133 storage_record_.persist_flag_map = 134 root_dir + "/maps/" + pb.container() + ".flag.map"; 135 storage_record_.persist_flag_val = 136 root_dir + "/flags/" + pb.container() + ".val"; 137 storage_record_.persist_flag_info = 138 root_dir + "/flags/" + pb.container() + ".info"; 139 storage_record_.local_overrides = 140 root_dir + "/flags/" + pb.container() + "_local_overrides.pb"; 141 storage_record_.boot_flag_val = 142 root_dir + "/boot/" + pb.container() + ".val"; 143 storage_record_.boot_flag_info = 144 root_dir + "/boot/" + pb.container() + ".info"; 145 storage_record_.digest = pb.digest(); 146 } 147 148 /// move constructor StorageFiles(StorageFiles && rhs)149 StorageFiles::StorageFiles(StorageFiles&& rhs) { 150 if (this != &rhs) { 151 *this = std::move(rhs); 152 } 153 } 154 155 /// move assignment operator =(StorageFiles && rhs)156 StorageFiles& StorageFiles::operator=(StorageFiles&& rhs) { 157 if (this != &rhs) { 158 container_ = rhs.container_; 159 storage_record_ = std::move(rhs.storage_record_); 160 package_map_ = std::move(rhs.package_map_); 161 flag_map_ = std::move(rhs.flag_map_); 162 flag_val_ = std::move(rhs.flag_val_); 163 boot_flag_val_ = std::move(rhs.boot_flag_val_); 164 boot_flag_info_ = std::move(rhs.boot_flag_info_); 165 persist_flag_val_ = std::move(rhs.persist_flag_val_); 166 persist_flag_info_ = std::move(rhs.persist_flag_info_); 167 } 168 return *this; 169 } 170 171 /// get package map GetPackageMap()172 base::Result<const MappedStorageFile*> StorageFiles::GetPackageMap() { 173 if (!package_map_) { 174 if (storage_record_.persist_package_map.empty()) { 175 return base::Error() << "Missing persist package map file"; 176 } 177 auto package_map = map_storage_file(storage_record_.persist_package_map); 178 RETURN_IF_ERROR(package_map, "Failed to map persist package map file for " + container_); 179 package_map_.reset(*package_map); 180 } 181 return package_map_.get(); 182 } 183 184 /// get flag map GetFlagMap()185 base::Result<const MappedStorageFile*> StorageFiles::GetFlagMap() { 186 if (!flag_map_) { 187 if (storage_record_.persist_flag_map.empty()) { 188 return base::Error() << "Missing persist flag map file"; 189 } 190 auto flag_map = map_storage_file(storage_record_.persist_flag_map); 191 RETURN_IF_ERROR(flag_map, "Failed to map persist flag map file for " + container_); 192 flag_map_.reset(*flag_map); 193 } 194 return flag_map_.get(); 195 } 196 197 /// get default flag val GetFlagVal()198 base::Result<const MappedStorageFile*> StorageFiles::GetFlagVal() { 199 if (!flag_val_) { 200 if (storage_record_.flag_val.empty()) { 201 return base::Error() << "Missing flag val file"; 202 } 203 auto flag_val = map_storage_file(storage_record_.flag_val); 204 RETURN_IF_ERROR(flag_val, "Failed to map flag val file for " + container_); 205 flag_val_.reset(*flag_val); 206 } 207 return flag_val_.get(); 208 } 209 210 /// get boot flag val GetBootFlagVal()211 base::Result<const MappedStorageFile*> StorageFiles::GetBootFlagVal() { 212 if (!boot_flag_val_) { 213 if (storage_record_.boot_flag_val.empty()) { 214 return base::Error() << "Missing boot flag val file"; 215 } 216 auto flag_val = map_storage_file(storage_record_.boot_flag_val); 217 RETURN_IF_ERROR(flag_val, "Failed to map boot flag val file for " + container_); 218 boot_flag_val_.reset(*flag_val); 219 } 220 return boot_flag_val_.get(); 221 } 222 223 /// get boot flag info GetBootFlagInfo()224 base::Result<const MappedStorageFile*> StorageFiles::GetBootFlagInfo() { 225 if (!boot_flag_info_) { 226 if (storage_record_.boot_flag_info.empty()) { 227 return base::Error() << "Missing boot flag info file"; 228 } 229 auto flag_info = map_storage_file(storage_record_.boot_flag_info); 230 RETURN_IF_ERROR(flag_info, "Failed to map boot flag info file for " + container_); 231 boot_flag_info_.reset(*flag_info); 232 } 233 return boot_flag_info_.get(); 234 } 235 236 /// get persist flag val GetPersistFlagVal()237 base::Result<const MutableMappedStorageFile*> StorageFiles::GetPersistFlagVal() { 238 if (!persist_flag_val_) { 239 if (storage_record_.persist_flag_val.empty()) { 240 return base::Error() << "Missing persist flag value file"; 241 } 242 auto flag_val = map_mutable_storage_file(storage_record_.persist_flag_val); 243 RETURN_IF_ERROR(flag_val, "Failed to map persist flag val file for " + container_); 244 persist_flag_val_.reset(*flag_val); 245 } 246 return persist_flag_val_.get(); 247 } 248 249 /// get persist flag info GetPersistFlagInfo()250 base::Result<const MutableMappedStorageFile*> StorageFiles::GetPersistFlagInfo() { 251 if (!persist_flag_info_) { 252 if (storage_record_.persist_flag_info.empty()) { 253 return base::Error() << "Missing persist flag info file"; 254 } 255 auto flag_info = map_mutable_storage_file(storage_record_.persist_flag_info); 256 RETURN_IF_ERROR(flag_info, "Failed to map persist flag info file for " + container_); 257 persist_flag_info_.reset(*flag_info); 258 } 259 return persist_flag_info_.get(); 260 } 261 262 /// check if flag is read only IsFlagReadOnly(const PackageFlagContext & context)263 base::Result<bool> StorageFiles::IsFlagReadOnly(const PackageFlagContext& context) { 264 if (!context.flag_exists) { 265 return base::Error() << "Flag does not exist"; 266 } 267 268 auto flag_info_file = GetPersistFlagInfo(); 269 if (!flag_info_file.ok()) { 270 return base::Error() << flag_info_file.error(); 271 } 272 273 auto attribute = get_flag_attribute( 274 **flag_info_file, context.value_type, context.flag_index); 275 276 if (!attribute.ok()) { 277 return base::Error() << "Failed to get flag attribute"; 278 } 279 280 return !(*attribute & FlagInfoBit::IsReadWrite); 281 } 282 283 /// apply local update to boot flag value copy ApplyLocalOverrideToBootFlagValue()284 base::Result<void> StorageFiles::ApplyLocalOverrideToBootFlagValue() { 285 auto flag_value_result = map_mutable_storage_file(storage_record_.boot_flag_val); 286 if (!flag_value_result.ok()) { 287 return base::Error() << "Failed to map boot flag value file for local override: " 288 << flag_value_result.error(); 289 } 290 auto flag_value = std::unique_ptr<MutableMappedStorageFile>(*flag_value_result); 291 292 auto pb_file = storage_record_.local_overrides; 293 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 294 if (!pb.ok()) { 295 return base::Error() << "Failed to read pb from " << pb_file << ": " << pb.error(); 296 } 297 298 auto applied_overrides = LocalFlagOverrides(); 299 for (auto& entry : pb->overrides()) { 300 301 // find flag value type and index 302 auto context = GetPackageFlagContext(entry.package_name(), entry.flag_name()); 303 if (!context.ok()) { 304 return base::Error() << "Failed to find flag: " << context.error(); 305 } 306 307 if (!context->flag_exists) { 308 continue; 309 } 310 311 // apply a local override 312 switch (context->value_type) { 313 case FlagValueType::Boolean: { 314 // validate value 315 if (entry.flag_value() != "true" && entry.flag_value() != "false") { 316 return base::Error() << "Invalid boolean flag value, it should be true|false"; 317 } 318 319 // update flag value 320 auto update_result = set_boolean_flag_value( 321 *flag_value, context->flag_index, entry.flag_value() == "true"); 322 if (!update_result.ok()) { 323 return base::Error() << "Failed to update flag value: " << update_result.error(); 324 } 325 326 break; 327 } 328 default: 329 return base::Error() << "Unsupported flag value type"; 330 } 331 332 // mark it applied 333 auto new_applied = applied_overrides.add_overrides(); 334 new_applied->set_package_name(entry.package_name()); 335 new_applied->set_flag_name(entry.flag_name()); 336 new_applied->set_flag_value(entry.flag_value()); 337 } 338 339 if (pb->overrides_size() != applied_overrides.overrides_size()) { 340 auto result = WritePbToFile<LocalFlagOverrides>(applied_overrides, pb_file); 341 if (!result.ok()) { 342 return base::Error() << result.error(); 343 } 344 } 345 346 return {}; 347 } 348 349 /// has boot copy HasBootCopy()350 bool StorageFiles::HasBootCopy() { 351 return FileExists(storage_record_.boot_flag_val) 352 && FileExists(storage_record_.boot_flag_info); 353 } 354 355 /// Find flag value type and global index GetPackageFlagContext(const std::string & package,const std::string & flag)356 base::Result<StorageFiles::PackageFlagContext> StorageFiles::GetPackageFlagContext( 357 const std::string& package, 358 const std::string& flag) { 359 auto result = PackageFlagContext(package, flag); 360 361 // early return 362 if (package.empty()) { 363 result.package_exists = false; 364 result.flag_exists = false; 365 return result; 366 } 367 368 // find package context 369 auto package_map = GetPackageMap(); 370 if (!package_map.ok()) { 371 return base::Error() << package_map.error(); 372 } 373 374 auto package_context = get_package_read_context(**package_map, package); 375 if (!package_context.ok()) { 376 return base::Error() << "Failed to get package context for " << package 377 << " in " << container_ << " :" << package_context.error(); 378 } 379 380 if (!package_context->package_exists) { 381 result.flag_exists = false; 382 return result; 383 } else { 384 result.package_exists = true; 385 } 386 387 // early return 388 if (flag.empty()) { 389 return result; 390 } 391 392 uint32_t package_id = package_context->package_id; 393 uint32_t boolean_flag_start_index = package_context->boolean_start_index; 394 395 // find flag context 396 auto flag_map = GetFlagMap(); 397 if (!flag_map.ok()) { 398 return base::Error() << flag_map.error(); 399 } 400 401 auto flag_context = get_flag_read_context(**flag_map, package_id, flag); 402 if (!flag_context.ok()) { 403 return base::Error() << "Failed to get flag context of " << package << "/" 404 << flag << " in " << container_ << " :" 405 << flag_context.error(); 406 } 407 408 if (!flag_context->flag_exists) { 409 result.flag_exists = false; 410 return result; 411 } 412 413 StoredFlagType stored_type = flag_context->flag_type; 414 uint16_t within_package_flag_index = flag_context->flag_index; 415 auto value_type = map_to_flag_value_type(stored_type); 416 if (!value_type.ok()) { 417 return base::Error() << "Failed to get flag value type :" << value_type.error(); 418 } 419 420 result.flag_exists = true; 421 result.value_type = *value_type; 422 result.flag_index = boolean_flag_start_index + within_package_flag_index; 423 return result; 424 } 425 426 /// check if has package HasPackage(const std::string & package)427 base::Result<bool> StorageFiles::HasPackage(const std::string& package) { 428 auto type_and_index = GetPackageFlagContext(package, ""); 429 if (!type_and_index.ok()) { 430 return base::Error() << type_and_index.error(); 431 } 432 return type_and_index->package_exists; 433 } 434 435 /// check if has flag HasFlag(const std::string & package,const std::string & flag)436 base::Result<bool> StorageFiles::HasFlag(const std::string& package, 437 const std::string& flag) { 438 auto type_and_index = GetPackageFlagContext(package, flag); 439 if (!type_and_index.ok()) { 440 return base::Error() << type_and_index.error(); 441 } 442 return type_and_index->flag_exists; 443 } 444 445 /// get persistent flag attribute GetFlagAttribute(const PackageFlagContext & context)446 base::Result<uint8_t> StorageFiles::GetFlagAttribute( 447 const PackageFlagContext& context) { 448 if (!context.flag_exists) { 449 return base::Error() << "Flag does not exist"; 450 } 451 452 auto flag_info_file = GetPersistFlagInfo(); 453 if (!flag_info_file.ok()) { 454 return base::Error() << flag_info_file.error(); 455 } 456 457 auto attribute = get_flag_attribute(**flag_info_file, context.value_type, context.flag_index); 458 if (!attribute.ok()) { 459 return base::Error() << "Failed to get flag info: " << attribute.error(); 460 } 461 462 return *attribute; 463 } 464 465 /// get server flag value GetServerFlagValue(const PackageFlagContext & context)466 base::Result<std::string> StorageFiles::GetServerFlagValue( 467 const PackageFlagContext& context) { 468 auto attribute = GetFlagAttribute(context); 469 RETURN_IF_ERROR(attribute, "Failed to get flag attribute"); 470 471 if (!(*attribute & FlagInfoBit::HasServerOverride)) { 472 return std::string(); 473 } 474 475 if (!context.flag_exists) { 476 return base::Error() << "Flag does not exist"; 477 } 478 479 auto flag_value_file = GetPersistFlagVal(); 480 if (!flag_value_file.ok()) { 481 return base::Error() << flag_value_file.error(); 482 } 483 484 switch (context.value_type) { 485 case FlagValueType::Boolean: { 486 auto value = get_boolean_flag_value(**flag_value_file, context.flag_index); 487 if (!value.ok()) { 488 return base::Error() << "Failed to get flag value: " << value.error(); 489 } 490 return *value ? "true" : "false"; 491 break; 492 } 493 default: 494 return base::Error() << "Unsupported flag value type"; 495 } 496 497 return base::Error() << "Failed to find flag in value file"; 498 } 499 500 /// get local flag value GetLocalFlagValue(const PackageFlagContext & context)501 base::Result<std::string> StorageFiles::GetLocalFlagValue( 502 const PackageFlagContext& context) { 503 auto attribute = GetFlagAttribute(context); 504 RETURN_IF_ERROR(attribute, "Failed to get flag attribute"); 505 506 if (!(*attribute & FlagInfoBit::HasLocalOverride)) { 507 return std::string(); 508 } 509 510 if (!context.flag_exists) { 511 return base::Error() << "Flag does not exist"; 512 } 513 514 auto pb_file = storage_record_.local_overrides; 515 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 516 if (!pb.ok()) { 517 return base::Error() << "Failed to read pb from " << pb_file << ": " << pb.error(); 518 } 519 520 for (auto& entry : pb->overrides()) { 521 if (context.package == entry.package_name() 522 && context.flag == entry.flag_name()) { 523 return entry.flag_value(); 524 } 525 } 526 527 return base::Error() << "Failed to find flag local override value"; 528 } 529 530 /// get boot flag value GetBootFlagValue(const PackageFlagContext & context)531 base::Result<std::string> StorageFiles::GetBootFlagValue( 532 const PackageFlagContext& context) { 533 if (!context.flag_exists) { 534 return base::Error() << "Flag does not exist"; 535 } 536 537 auto flag_value_file = GetBootFlagVal(); 538 if (!flag_value_file.ok()) { 539 return base::Error() << flag_value_file.error(); 540 } 541 542 switch (context.value_type) { 543 case FlagValueType::Boolean: { 544 auto value = get_boolean_flag_value(**flag_value_file, context.flag_index); 545 if (!value.ok()) { 546 return base::Error() << "Failed to get boot flag value: " << value.error(); 547 } 548 return *value ? "true" : "false"; 549 break; 550 } 551 default: 552 return base::Error() << "Unsupported flag value type"; 553 } 554 555 return base::Error() << "Failed to find flag in value file"; 556 } 557 558 /// get default flag value GetDefaultFlagValue(const PackageFlagContext & context)559 base::Result<std::string> StorageFiles::GetDefaultFlagValue( 560 const PackageFlagContext& context) { 561 if (!context.flag_exists) { 562 return base::Error() << "Flag does not exist"; 563 } 564 565 auto flag_value_file = GetFlagVal(); 566 if (!flag_value_file.ok()) { 567 return base::Error() << flag_value_file.error(); 568 } 569 570 switch (context.value_type) { 571 case FlagValueType::Boolean: { 572 auto value = get_boolean_flag_value(**flag_value_file, context.flag_index); 573 if (!value.ok()) { 574 return base::Error() << "Failed to get default flag value: " << value.error(); 575 } 576 return *value ? "true" : "false"; 577 break; 578 } 579 default: 580 return base::Error() << "Unsupported flag value type"; 581 } 582 583 return base::Error() << "Failed to find flag in value file"; 584 } 585 586 /// server flag override, update persistent flag value SetServerFlagValue(const PackageFlagContext & context,const std::string & flag_value)587 base::Result<void> StorageFiles::SetServerFlagValue(const PackageFlagContext& context, 588 const std::string& flag_value) { 589 if (!context.flag_exists) { 590 return base::Error() << "Flag does not exist"; 591 } 592 593 auto readonly = IsFlagReadOnly(context); 594 RETURN_IF_ERROR(readonly, "Failed to check if flag is readonly"); 595 if (*readonly) { 596 return base::Error() << "Cannot update read only flag"; 597 } 598 599 auto flag_value_file = GetPersistFlagVal(); 600 RETURN_IF_ERROR(flag_value_file, "Cannot get persist flag value file"); 601 602 switch (context.value_type) { 603 case FlagValueType::Boolean: { 604 if (flag_value != "true" && flag_value != "false") { 605 return base::Error() << "Invalid boolean flag value, it should be true|false"; 606 } 607 608 auto update = set_boolean_flag_value( 609 **flag_value_file, context.flag_index, flag_value == "true"); 610 RETURN_IF_ERROR(update, "Failed to update flag value"); 611 612 update = SetHasServerOverride(context, true); 613 RETURN_IF_ERROR(update, "Failed to set flag has server override"); 614 615 break; 616 } 617 default: 618 return base::Error() << "Unsupported flag value type"; 619 } 620 621 return {}; 622 } 623 624 /// local flag override, update local flag override pb filee SetLocalFlagValue(const PackageFlagContext & context,const std::string & flag_value)625 base::Result<void> StorageFiles::SetLocalFlagValue(const PackageFlagContext& context, 626 const std::string& flag_value) { 627 if (!context.flag_exists) { 628 return base::Error() << "Flag does not exist"; 629 } 630 631 auto readonly = IsFlagReadOnly(context); 632 RETURN_IF_ERROR(readonly, "Failed to check if flag is readonly") 633 if (*readonly) { 634 return base::Error() << "Cannot update read only flag"; 635 } 636 637 auto pb_file = storage_record_.local_overrides; 638 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 639 if (!pb.ok()) { 640 return base::Error() << "Failed to read pb from " << pb_file << ": " << pb.error(); 641 } 642 643 bool exist = false; 644 for (auto& entry : *(pb->mutable_overrides())) { 645 if (entry.package_name() == context.package 646 && entry.flag_name() == context.flag) { 647 if (entry.flag_value() == flag_value) { 648 return {}; 649 } 650 exist = true; 651 entry.set_flag_value(flag_value); 652 break; 653 } 654 } 655 656 if (!exist) { 657 auto new_override = pb->add_overrides(); 658 new_override->set_package_name(context.package); 659 new_override->set_flag_name(context.flag); 660 new_override->set_flag_value(flag_value); 661 } 662 663 auto write = WritePbToFile<LocalFlagOverrides>(*pb, pb_file); 664 if (!write.ok()) { 665 return base::Error() << "Failed to write pb to " << pb_file << ": " << write.error(); 666 } 667 668 auto update = SetHasLocalOverride(context, true); 669 RETURN_IF_ERROR(update, "Failed to set flag has local override"); 670 671 return {}; 672 } 673 674 /// set has server override in flag info SetHasServerOverride(const PackageFlagContext & context,bool has_server_override)675 base::Result<void> StorageFiles::SetHasServerOverride(const PackageFlagContext& context, 676 bool has_server_override) { 677 if (!context.flag_exists) { 678 return base::Error() << "Flag does not exist"; 679 } 680 681 auto flag_info_file = GetPersistFlagInfo(); 682 if (!flag_info_file.ok()) { 683 return base::Error() << flag_info_file.error(); 684 } 685 686 auto update_result = set_flag_has_server_override( 687 **flag_info_file, context.value_type, context.flag_index, has_server_override); 688 if (!update_result.ok()) { 689 return base::Error() << "Failed to update flag has server override: " 690 << update_result.error(); 691 } 692 693 return {}; 694 } 695 696 /// set has local override in flag info SetHasLocalOverride(const PackageFlagContext & context,bool has_local_override)697 base::Result<void> StorageFiles::SetHasLocalOverride(const PackageFlagContext& context, 698 bool has_local_override) { 699 if (!context.flag_exists) { 700 return base::Error() << "Flag does not exist"; 701 } 702 703 auto flag_info_file = GetPersistFlagInfo(); 704 if (!flag_info_file.ok()) { 705 return base::Error() << flag_info_file.error(); 706 } 707 708 auto update_result = set_flag_has_local_override( 709 **flag_info_file, context.value_type, context.flag_index, has_local_override); 710 if (!update_result.ok()) { 711 return base::Error() << "Failed to update flag has local override: " 712 << update_result.error(); 713 } 714 715 return {}; 716 } 717 718 /// remove a single flag local override, return if removed RemoveLocalFlagValue(const PackageFlagContext & context)719 base::Result<bool> StorageFiles::RemoveLocalFlagValue( 720 const PackageFlagContext& context) { 721 722 auto pb_file = storage_record_.local_overrides; 723 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 724 if (!pb.ok()) { 725 return base::Error() << "Failed to read pb from " << pb_file << ": " << pb.error(); 726 } 727 728 auto remaining_overrides = LocalFlagOverrides(); 729 for (auto entry : pb->overrides()) { 730 if (entry.package_name() == context.package 731 && entry.flag_name() == context.flag) { 732 continue; 733 } 734 auto kept_override = remaining_overrides.add_overrides(); 735 kept_override->set_package_name(entry.package_name()); 736 kept_override->set_flag_name(entry.flag_name()); 737 kept_override->set_flag_value(entry.flag_value()); 738 } 739 740 if (remaining_overrides.overrides_size() != pb->overrides_size()) { 741 auto result = WritePbToFile<LocalFlagOverrides>(remaining_overrides, pb_file); 742 if (!result.ok()) { 743 return base::Error() << result.error(); 744 } 745 746 auto update = SetHasLocalOverride(context, false); 747 RETURN_IF_ERROR(update, "Failed to unset flag has local override"); 748 749 return true; 750 } else { 751 return false; 752 } 753 } 754 755 /// remove all local overrides RemoveAllLocalFlagValue()756 base::Result<void> StorageFiles::RemoveAllLocalFlagValue() { 757 auto pb_file = storage_record_.local_overrides; 758 auto overrides_pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 759 RETURN_IF_ERROR(overrides_pb, "Failed to read local overrides"); 760 761 for (auto& entry : overrides_pb->overrides()) { 762 auto context = GetPackageFlagContext(entry.package_name(), entry.flag_name()); 763 RETURN_IF_ERROR(context, "Failed to find package flag context for flag " 764 + entry.package_name() + "/" + entry.flag_name()); 765 766 auto update = SetHasLocalOverride(*context, false); 767 RETURN_IF_ERROR(update, "Failed to unset flag has local override"); 768 } 769 770 if (overrides_pb->overrides_size()) { 771 auto result = WritePbToFile<LocalFlagOverrides>( 772 LocalFlagOverrides(), pb_file); 773 RETURN_IF_ERROR(result, "Failed to flush local overrides pb file"); 774 } 775 776 return {}; 777 } 778 779 /// get all current server override 780 base::Result<std::vector<StorageFiles::ServerOverride>> GetServerFlagValues()781 StorageFiles::GetServerFlagValues() { 782 auto listed_flags = list_flags_with_info(storage_record_.persist_package_map, 783 storage_record_.persist_flag_map, 784 storage_record_.persist_flag_val, 785 storage_record_.persist_flag_info); 786 RETURN_IF_ERROR( 787 listed_flags, "Failed to list all flags for " + storage_record_.container); 788 789 auto server_updated_flags = std::vector<ServerOverride>(); 790 for (const auto& flag : *listed_flags) { 791 if (flag.has_server_override) { 792 auto server_override = ServerOverride(); 793 server_override.package_name = std::move(flag.package_name); 794 server_override.flag_name = std::move(flag.flag_name); 795 server_override.flag_value = std::move(flag.flag_value); 796 server_updated_flags.push_back(server_override); 797 } 798 } 799 800 return server_updated_flags; 801 } 802 803 /// remove all storage files RemoveAllPersistFiles()804 base::Result<void> StorageFiles::RemoveAllPersistFiles() { 805 package_map_.reset(nullptr); 806 flag_map_.reset(nullptr); 807 flag_val_.reset(nullptr); 808 boot_flag_val_.reset(nullptr); 809 boot_flag_info_.reset(nullptr); 810 persist_flag_val_.reset(nullptr); 811 persist_flag_info_.reset(nullptr); 812 if (unlink(storage_record_.persist_package_map.c_str()) == -1) { 813 return base::ErrnoError() << "unlink() failed for " 814 << storage_record_.persist_package_map; 815 } 816 if (unlink(storage_record_.persist_flag_map.c_str()) == -1) { 817 return base::ErrnoError() << "unlink() failed for " 818 << storage_record_.persist_flag_map; 819 } 820 if (unlink(storage_record_.persist_flag_val.c_str()) == -1) { 821 return base::ErrnoError() << "unlink() failed for " 822 << storage_record_.persist_flag_val; 823 } 824 if (unlink(storage_record_.persist_flag_info.c_str()) == -1) { 825 return base::ErrnoError() << "unlink() failed for " 826 << storage_record_.persist_flag_info; 827 } 828 if (unlink(storage_record_.local_overrides.c_str()) == -1) { 829 return base::ErrnoError() << "unlink() failed for " << storage_record_.local_overrides; 830 } 831 return {}; 832 } 833 834 /// create boot flag value and info files CreateBootStorageFiles()835 base::Result<void> StorageFiles::CreateBootStorageFiles() { 836 // If the boot copy already exists, do nothing. Never update the boot copy, the boot 837 // copy should be boot stable. So in the following scenario: a container storage 838 // file boot copy is created, then an updated container is mounted along side existing 839 // container. In this case, we should update the persistent storage file copy. But 840 // never touch the current boot copy. 841 if (FileExists(storage_record_.boot_flag_val) 842 && FileExists(storage_record_.boot_flag_info)) { 843 return {}; 844 } 845 846 auto copy = CopyFile( 847 storage_record_.persist_flag_val, storage_record_.boot_flag_val, 0444); 848 RETURN_IF_ERROR(copy, "CopyFile failed for " + storage_record_.persist_flag_val); 849 850 copy = CopyFile( 851 storage_record_.persist_flag_info, storage_record_.boot_flag_info, 0444); 852 RETURN_IF_ERROR(copy, "CopyFile failed for " + storage_record_.persist_flag_info); 853 854 // change boot flag value file to 0644 to allow write 855 if (chmod(storage_record_.boot_flag_val.c_str(), 0644) == -1) { 856 return base::ErrnoError() << "chmod() failed to set to 0644"; 857 }; 858 859 auto apply_result = ApplyLocalOverrideToBootFlagValue(); 860 861 // change boot flag value file back to 0444 862 if (chmod(storage_record_.boot_flag_val.c_str(), 0444) == -1) { 863 if (!apply_result.ok()) { 864 return base::ErrnoError() << apply_result.error() << ": " 865 << "chmod() failed to set to 0444"; 866 } else { 867 return base::ErrnoError() << "chmod() failed to set to 0444"; 868 } 869 }; 870 871 return apply_result; 872 } 873 874 /// list a flag ListFlag(const std::string & package,const std::string & flag)875 base::Result<StorageFiles::FlagSnapshot> StorageFiles::ListFlag( 876 const std::string& package, 877 const std::string& flag) { 878 879 auto context = GetPackageFlagContext(package, flag); 880 RETURN_IF_ERROR(context, "Failed to find package flag context"); 881 882 if (!context->flag_exists) { 883 return base::Error() << "Flag " << package << "/" << flag << " does not exist"; 884 } 885 886 auto attribute = GetFlagAttribute(*context); 887 RETURN_IF_ERROR(context, "Failed to get flag attribute"); 888 889 auto server_value = GetServerFlagValue(*context); 890 RETURN_IF_ERROR(server_value, "Failed to get server flag value"); 891 892 auto local_value = GetLocalFlagValue(*context); 893 RETURN_IF_ERROR(local_value, "Failed to get local flag value"); 894 895 auto boot_value = GetBootFlagValue(*context); 896 RETURN_IF_ERROR(boot_value, "Failed to get boot flag value"); 897 898 auto default_value = GetDefaultFlagValue(*context); 899 RETURN_IF_ERROR(default_value, "Failed to get default flag value"); 900 901 auto snapshot = FlagSnapshot(); 902 snapshot.package_name = package; 903 snapshot.flag_name = flag; 904 snapshot.default_flag_value = *default_value; 905 snapshot.boot_flag_value = *boot_value; 906 snapshot.server_flag_value = *server_value; 907 snapshot.local_flag_value = *local_value; 908 snapshot.is_readwrite = *attribute & FlagInfoBit::IsReadWrite; 909 snapshot.has_server_override = *attribute & FlagInfoBit::HasServerOverride; 910 snapshot.has_local_override = *attribute & FlagInfoBit::HasLocalOverride; 911 912 return snapshot; 913 } 914 915 /// list flags ListFlags(const std::string & package)916 base::Result<std::vector<StorageFiles::FlagSnapshot>> StorageFiles::ListFlags( 917 const std::string& package) { 918 if (!package.empty()) { 919 auto has_package = HasPackage(package); 920 RETURN_IF_ERROR( 921 has_package, package + " does not exist in " + storage_record_.container); 922 } 923 924 // fill default value 925 auto snapshots = std::vector<FlagSnapshot>(); 926 auto idxs = std::unordered_map<std::string, size_t>(); 927 928 auto listed_flags = list_flags(storage_record_.package_map, 929 storage_record_.flag_map, 930 storage_record_.flag_val); 931 RETURN_IF_ERROR( 932 listed_flags, "Failed to list default flags for " + storage_record_.container); 933 934 for (auto const& flag : *listed_flags) { 935 if (package.empty() || package == flag.package_name) { 936 idxs[flag.package_name + "/" + flag.flag_name] = snapshots.size(); 937 snapshots.emplace_back(); 938 auto& snapshot = snapshots.back(); 939 snapshot.package_name = std::move(flag.package_name); 940 snapshot.flag_name = std::move(flag.flag_name); 941 snapshot.default_flag_value = std::move(flag.flag_value); 942 } 943 } 944 945 // fill boot value 946 listed_flags = list_flags(storage_record_.package_map, 947 storage_record_.flag_map, 948 storage_record_.boot_flag_val); 949 RETURN_IF_ERROR( 950 listed_flags, "Failed to list boot flags for " + storage_record_.container); 951 952 for (auto const& flag : *listed_flags) { 953 auto full_flag_name = flag.package_name + "/" + flag.flag_name; 954 if (!idxs.count(full_flag_name)) { 955 continue; 956 } 957 auto idx = idxs[full_flag_name]; 958 snapshots[idx].boot_flag_value = std::move(flag.flag_value); 959 } 960 961 // fill server value and attribute 962 auto listed_flags_with_info = list_flags_with_info(storage_record_.package_map, 963 storage_record_.flag_map, 964 storage_record_.persist_flag_val, 965 storage_record_.persist_flag_info); 966 RETURN_IF_ERROR(listed_flags_with_info, 967 "Failed to list persist flags for " + storage_record_.container); 968 969 for (auto const& flag : *listed_flags_with_info) { 970 auto full_flag_name = flag.package_name + "/" + flag.flag_name; 971 if (!idxs.count(full_flag_name)) { 972 continue; 973 } 974 auto idx = idxs[full_flag_name]; 975 if (flag.has_server_override) { 976 snapshots[idx].server_flag_value = std::move(flag.flag_value); 977 } 978 snapshots[idx].is_readwrite = flag.is_readwrite; 979 snapshots[idx].has_server_override = flag.has_server_override; 980 snapshots[idx].has_local_override = flag.has_local_override; 981 } 982 983 // fill local value 984 auto const& pb_file = storage_record_.local_overrides; 985 auto pb = ReadPbFromFile<LocalFlagOverrides>(pb_file); 986 RETURN_IF_ERROR(pb, "Failed to read pb from " + pb_file); 987 for (const auto& flag : pb->overrides()) { 988 auto full_flag_name = flag.package_name() + "/" + flag.flag_name(); 989 if (!idxs.count(full_flag_name)) { 990 continue; 991 } 992 auto idx = idxs[full_flag_name]; 993 snapshots[idx].local_flag_value = flag.flag_value(); 994 } 995 996 auto comp = [](const auto& v1, const auto& v2){ 997 return (v1.package_name + "/" + v1.flag_name) < 998 (v2.package_name + "/" + v2.flag_name); 999 }; 1000 std::sort(snapshots.begin(), snapshots.end(), comp); 1001 1002 return snapshots; 1003 } 1004 1005 } // namespace aconfigd 1006 } // namespace android 1007