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