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