xref: /aosp_15_r20/system/server_configurable_flags/aconfigd/aconfigd.cpp (revision 207333786ba243bc7d4d69ef6b05487aa7071806)
1*20733378SAndroid Build Coastguard Worker /*
2*20733378SAndroid Build Coastguard Worker  * Copyright (C) 2024 The Android Open Source Project
3*20733378SAndroid Build Coastguard Worker  *
4*20733378SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*20733378SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*20733378SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*20733378SAndroid Build Coastguard Worker  *
8*20733378SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*20733378SAndroid Build Coastguard Worker  *
10*20733378SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*20733378SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*20733378SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*20733378SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*20733378SAndroid Build Coastguard Worker  * limitations under the License.
15*20733378SAndroid Build Coastguard Worker  */
16*20733378SAndroid Build Coastguard Worker 
17*20733378SAndroid Build Coastguard Worker #include <memory>
18*20733378SAndroid Build Coastguard Worker #include <string>
19*20733378SAndroid Build Coastguard Worker #include <dirent.h>
20*20733378SAndroid Build Coastguard Worker 
21*20733378SAndroid Build Coastguard Worker #include <android-base/file.h>
22*20733378SAndroid Build Coastguard Worker #include <android-base/logging.h>
23*20733378SAndroid Build Coastguard Worker #include <android-base/properties.h>
24*20733378SAndroid Build Coastguard Worker 
25*20733378SAndroid Build Coastguard Worker #include "storage_files_manager.h"
26*20733378SAndroid Build Coastguard Worker #include "aconfigd_util.h"
27*20733378SAndroid Build Coastguard Worker #include "aconfigd.h"
28*20733378SAndroid Build Coastguard Worker 
29*20733378SAndroid Build Coastguard Worker using namespace android::base;
30*20733378SAndroid Build Coastguard Worker 
31*20733378SAndroid Build Coastguard Worker namespace android {
32*20733378SAndroid Build Coastguard Worker namespace aconfigd {
33*20733378SAndroid Build Coastguard Worker 
34*20733378SAndroid Build Coastguard Worker /// Handle a flag override request
HandleFlagOverride(const StorageRequestMessage::FlagOverrideMessage & msg,StorageReturnMessage & return_msg)35*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::HandleFlagOverride(
36*20733378SAndroid Build Coastguard Worker     const StorageRequestMessage::FlagOverrideMessage& msg,
37*20733378SAndroid Build Coastguard Worker     StorageReturnMessage& return_msg) {
38*20733378SAndroid Build Coastguard Worker   auto result = storage_files_manager_->UpdateFlagValue(
39*20733378SAndroid Build Coastguard Worker       msg.package_name(), msg.flag_name(), msg.flag_value(),
40*20733378SAndroid Build Coastguard Worker       msg.override_type());
41*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(result, "Failed to set flag override");
42*20733378SAndroid Build Coastguard Worker   return_msg.mutable_flag_override_message();
43*20733378SAndroid Build Coastguard Worker   return {};
44*20733378SAndroid Build Coastguard Worker }
45*20733378SAndroid Build Coastguard Worker 
46*20733378SAndroid Build Coastguard Worker /// Handle ota flag staging request
HandleOTAStaging(const StorageRequestMessage::OTAFlagStagingMessage & msg,StorageReturnMessage & return_msg)47*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::HandleOTAStaging(
48*20733378SAndroid Build Coastguard Worker     const StorageRequestMessage::OTAFlagStagingMessage& msg,
49*20733378SAndroid Build Coastguard Worker     StorageReturnMessage& return_msg) {
50*20733378SAndroid Build Coastguard Worker   auto ota_flags_pb_file = root_dir_ + "/flags/ota.pb";
51*20733378SAndroid Build Coastguard Worker   auto stored_pb_result =
52*20733378SAndroid Build Coastguard Worker       ReadPbFromFile<StorageRequestMessage::OTAFlagStagingMessage>(
53*20733378SAndroid Build Coastguard Worker           ota_flags_pb_file);
54*20733378SAndroid Build Coastguard Worker 
55*20733378SAndroid Build Coastguard Worker   if (!stored_pb_result.ok() ||
56*20733378SAndroid Build Coastguard Worker       (msg.build_id() != (*stored_pb_result).build_id())) {
57*20733378SAndroid Build Coastguard Worker     LOG(INFO) << "discarding staged flags from " +
58*20733378SAndroid Build Coastguard Worker                      (*stored_pb_result).build_id() +
59*20733378SAndroid Build Coastguard Worker                      "; staging new flags for " + msg.build_id();
60*20733378SAndroid Build Coastguard Worker     auto result = WritePbToFile<StorageRequestMessage::OTAFlagStagingMessage>(
61*20733378SAndroid Build Coastguard Worker         msg, ota_flags_pb_file);
62*20733378SAndroid Build Coastguard Worker     RETURN_IF_ERROR(result, "Failed to stage OTA flags");
63*20733378SAndroid Build Coastguard Worker     return_msg.mutable_ota_staging_message();
64*20733378SAndroid Build Coastguard Worker     return {};
65*20733378SAndroid Build Coastguard Worker   }
66*20733378SAndroid Build Coastguard Worker 
67*20733378SAndroid Build Coastguard Worker   std::set<std::string> qualified_names;
68*20733378SAndroid Build Coastguard Worker 
69*20733378SAndroid Build Coastguard Worker   std::map<std::string, android::aconfigd::FlagOverride> new_name_to_override;
70*20733378SAndroid Build Coastguard Worker   for (const auto& flag_override : msg.overrides()) {
71*20733378SAndroid Build Coastguard Worker     auto qualified_name =
72*20733378SAndroid Build Coastguard Worker         flag_override.package_name() + "." + flag_override.flag_name();
73*20733378SAndroid Build Coastguard Worker     new_name_to_override[qualified_name] = flag_override;
74*20733378SAndroid Build Coastguard Worker 
75*20733378SAndroid Build Coastguard Worker     qualified_names.insert(qualified_name);
76*20733378SAndroid Build Coastguard Worker   }
77*20733378SAndroid Build Coastguard Worker 
78*20733378SAndroid Build Coastguard Worker   std::map<std::string, android::aconfigd::FlagOverride> prev_name_to_override;
79*20733378SAndroid Build Coastguard Worker   for (const auto& flag_override : (*stored_pb_result).overrides()) {
80*20733378SAndroid Build Coastguard Worker     auto qualified_name =
81*20733378SAndroid Build Coastguard Worker         flag_override.package_name() + "." + flag_override.flag_name();
82*20733378SAndroid Build Coastguard Worker     prev_name_to_override[qualified_name] = flag_override;
83*20733378SAndroid Build Coastguard Worker 
84*20733378SAndroid Build Coastguard Worker     qualified_names.insert(qualified_name);
85*20733378SAndroid Build Coastguard Worker   }
86*20733378SAndroid Build Coastguard Worker 
87*20733378SAndroid Build Coastguard Worker   std::vector<android::aconfigd::FlagOverride> overrides;
88*20733378SAndroid Build Coastguard Worker   for (const auto& qualified_name : qualified_names) {
89*20733378SAndroid Build Coastguard Worker     if (new_name_to_override.contains(qualified_name)) {
90*20733378SAndroid Build Coastguard Worker       overrides.push_back(new_name_to_override[qualified_name]);
91*20733378SAndroid Build Coastguard Worker     } else {
92*20733378SAndroid Build Coastguard Worker       overrides.push_back(prev_name_to_override[qualified_name]);
93*20733378SAndroid Build Coastguard Worker     }
94*20733378SAndroid Build Coastguard Worker   }
95*20733378SAndroid Build Coastguard Worker 
96*20733378SAndroid Build Coastguard Worker   StorageRequestMessage::OTAFlagStagingMessage message_to_persist;
97*20733378SAndroid Build Coastguard Worker   message_to_persist.set_build_id(msg.build_id());
98*20733378SAndroid Build Coastguard Worker   for (const auto& flag_override : overrides) {
99*20733378SAndroid Build Coastguard Worker     auto override_ = message_to_persist.add_overrides();
100*20733378SAndroid Build Coastguard Worker     override_->set_flag_name(flag_override.flag_name());
101*20733378SAndroid Build Coastguard Worker     override_->set_package_name(flag_override.package_name());
102*20733378SAndroid Build Coastguard Worker     override_->set_flag_value(flag_override.flag_value());
103*20733378SAndroid Build Coastguard Worker   }
104*20733378SAndroid Build Coastguard Worker 
105*20733378SAndroid Build Coastguard Worker   auto result = WritePbToFile<StorageRequestMessage::OTAFlagStagingMessage>(
106*20733378SAndroid Build Coastguard Worker       message_to_persist, ota_flags_pb_file);
107*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(result, "Failed to stage OTA flags");
108*20733378SAndroid Build Coastguard Worker   return_msg.mutable_ota_staging_message();
109*20733378SAndroid Build Coastguard Worker   return {};
110*20733378SAndroid Build Coastguard Worker }
111*20733378SAndroid Build Coastguard Worker 
112*20733378SAndroid Build Coastguard Worker /// Handle new storage request
HandleNewStorage(const StorageRequestMessage::NewStorageMessage & msg,StorageReturnMessage & return_msg)113*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::HandleNewStorage(
114*20733378SAndroid Build Coastguard Worker     const StorageRequestMessage::NewStorageMessage& msg,
115*20733378SAndroid Build Coastguard Worker     StorageReturnMessage& return_msg) {
116*20733378SAndroid Build Coastguard Worker   auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
117*20733378SAndroid Build Coastguard Worker       msg.container(), msg.package_map(), msg.flag_map(), msg.flag_value(),
118*20733378SAndroid Build Coastguard Worker       msg.flag_info());
119*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(updated, "Failed to add or update container");
120*20733378SAndroid Build Coastguard Worker 
121*20733378SAndroid Build Coastguard Worker   auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
122*20733378SAndroid Build Coastguard Worker       persist_storage_records_);
123*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
124*20733378SAndroid Build Coastguard Worker 
125*20733378SAndroid Build Coastguard Worker   auto copy = storage_files_manager_->CreateStorageBootCopy(msg.container());
126*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(copy, "Failed to make a boot copy for " + msg.container());
127*20733378SAndroid Build Coastguard Worker 
128*20733378SAndroid Build Coastguard Worker   auto result_msg = return_msg.mutable_new_storage_message();
129*20733378SAndroid Build Coastguard Worker   result_msg->set_storage_updated(*updated);
130*20733378SAndroid Build Coastguard Worker   return {};
131*20733378SAndroid Build Coastguard Worker }
132*20733378SAndroid Build Coastguard Worker 
133*20733378SAndroid Build Coastguard Worker /// Handle a flag query request
HandleFlagQuery(const StorageRequestMessage::FlagQueryMessage & msg,StorageReturnMessage & return_msg)134*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::HandleFlagQuery(
135*20733378SAndroid Build Coastguard Worker     const StorageRequestMessage::FlagQueryMessage& msg,
136*20733378SAndroid Build Coastguard Worker     StorageReturnMessage& return_msg) {
137*20733378SAndroid Build Coastguard Worker   auto snapshot = storage_files_manager_->ListFlag(msg.package_name(), msg.flag_name());
138*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(snapshot, "Failed query failed");
139*20733378SAndroid Build Coastguard Worker   auto result_msg = return_msg.mutable_flag_query_message();
140*20733378SAndroid Build Coastguard Worker   result_msg->set_package_name(snapshot->package_name);
141*20733378SAndroid Build Coastguard Worker   result_msg->set_flag_name(snapshot->flag_name);
142*20733378SAndroid Build Coastguard Worker   result_msg->set_server_flag_value(snapshot->server_flag_value);
143*20733378SAndroid Build Coastguard Worker   result_msg->set_local_flag_value(snapshot->local_flag_value);
144*20733378SAndroid Build Coastguard Worker   result_msg->set_boot_flag_value(snapshot->boot_flag_value);
145*20733378SAndroid Build Coastguard Worker   result_msg->set_default_flag_value(snapshot->default_flag_value);
146*20733378SAndroid Build Coastguard Worker   result_msg->set_has_server_override(snapshot->has_server_override);
147*20733378SAndroid Build Coastguard Worker   result_msg->set_is_readwrite(snapshot->is_readwrite);
148*20733378SAndroid Build Coastguard Worker   result_msg->set_has_local_override(snapshot->has_local_override);
149*20733378SAndroid Build Coastguard Worker   return {};
150*20733378SAndroid Build Coastguard Worker }
151*20733378SAndroid Build Coastguard Worker 
152*20733378SAndroid Build Coastguard Worker /// Handle override removal request
HandleLocalOverrideRemoval(const StorageRequestMessage::RemoveLocalOverrideMessage & msg,StorageReturnMessage & return_msg)153*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::HandleLocalOverrideRemoval(
154*20733378SAndroid Build Coastguard Worker     const StorageRequestMessage::RemoveLocalOverrideMessage& msg,
155*20733378SAndroid Build Coastguard Worker     StorageReturnMessage& return_msg) {
156*20733378SAndroid Build Coastguard Worker   auto result = Result<void>();
157*20733378SAndroid Build Coastguard Worker   if (msg.remove_all()) {
158*20733378SAndroid Build Coastguard Worker     result = storage_files_manager_->RemoveAllLocalOverrides(
159*20733378SAndroid Build Coastguard Worker         msg.remove_override_type());
160*20733378SAndroid Build Coastguard Worker   } else {
161*20733378SAndroid Build Coastguard Worker     result = storage_files_manager_->RemoveFlagLocalOverride(
162*20733378SAndroid Build Coastguard Worker         msg.package_name(), msg.flag_name(), msg.remove_override_type());
163*20733378SAndroid Build Coastguard Worker   }
164*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(result, "");
165*20733378SAndroid Build Coastguard Worker   return_msg.mutable_remove_local_override_message();
166*20733378SAndroid Build Coastguard Worker   return {};
167*20733378SAndroid Build Coastguard Worker }
168*20733378SAndroid Build Coastguard Worker 
169*20733378SAndroid Build Coastguard Worker /// Handle storage reset
HandleStorageReset(StorageReturnMessage & return_msg)170*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::HandleStorageReset(StorageReturnMessage& return_msg) {
171*20733378SAndroid Build Coastguard Worker   auto result = storage_files_manager_->ResetAllStorage();
172*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(result, "Failed to reset all storage");
173*20733378SAndroid Build Coastguard Worker 
174*20733378SAndroid Build Coastguard Worker   result = storage_files_manager_->WritePersistStorageRecordsToFile(
175*20733378SAndroid Build Coastguard Worker       persist_storage_records_);
176*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(result, "Failed to write persist storage records");
177*20733378SAndroid Build Coastguard Worker 
178*20733378SAndroid Build Coastguard Worker   return_msg.mutable_reset_storage_message();
179*20733378SAndroid Build Coastguard Worker   return {};
180*20733378SAndroid Build Coastguard Worker }
181*20733378SAndroid Build Coastguard Worker 
182*20733378SAndroid Build Coastguard Worker /// Handle list storage
HandleListStorage(const StorageRequestMessage::ListStorageMessage & msg,StorageReturnMessage & return_message)183*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::HandleListStorage(
184*20733378SAndroid Build Coastguard Worker     const StorageRequestMessage::ListStorageMessage& msg,
185*20733378SAndroid Build Coastguard Worker     StorageReturnMessage& return_message) {
186*20733378SAndroid Build Coastguard Worker   auto flags = Result<std::vector<StorageFiles::FlagSnapshot>>();
187*20733378SAndroid Build Coastguard Worker   switch (msg.msg_case()) {
188*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::ListStorageMessage::kAll: {
189*20733378SAndroid Build Coastguard Worker       flags = storage_files_manager_->ListAllAvailableFlags();
190*20733378SAndroid Build Coastguard Worker       break;
191*20733378SAndroid Build Coastguard Worker     }
192*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::ListStorageMessage::kContainer: {
193*20733378SAndroid Build Coastguard Worker       flags = storage_files_manager_->ListFlagsInContainer(msg.container());
194*20733378SAndroid Build Coastguard Worker       break;
195*20733378SAndroid Build Coastguard Worker     }
196*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::ListStorageMessage::kPackageName: {
197*20733378SAndroid Build Coastguard Worker       flags = storage_files_manager_->ListFlagsInPackage(msg.package_name());
198*20733378SAndroid Build Coastguard Worker       break;
199*20733378SAndroid Build Coastguard Worker     }
200*20733378SAndroid Build Coastguard Worker     default:
201*20733378SAndroid Build Coastguard Worker       return Error() << "Unknown list storage message type from aconfigd socket";
202*20733378SAndroid Build Coastguard Worker   }
203*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(flags, "Failed to list flags");
204*20733378SAndroid Build Coastguard Worker 
205*20733378SAndroid Build Coastguard Worker   auto* result_msg = return_message.mutable_list_storage_message();
206*20733378SAndroid Build Coastguard Worker   for (const auto& flag : *flags) {
207*20733378SAndroid Build Coastguard Worker     auto* flag_msg = result_msg->add_flags();
208*20733378SAndroid Build Coastguard Worker     flag_msg->set_package_name(flag.package_name);
209*20733378SAndroid Build Coastguard Worker     flag_msg->set_flag_name(flag.flag_name);
210*20733378SAndroid Build Coastguard Worker     flag_msg->set_server_flag_value(flag.server_flag_value);
211*20733378SAndroid Build Coastguard Worker     flag_msg->set_local_flag_value(flag.local_flag_value);
212*20733378SAndroid Build Coastguard Worker     flag_msg->set_boot_flag_value(flag.boot_flag_value);
213*20733378SAndroid Build Coastguard Worker     flag_msg->set_default_flag_value(flag.default_flag_value);
214*20733378SAndroid Build Coastguard Worker     flag_msg->set_is_readwrite(flag.is_readwrite);
215*20733378SAndroid Build Coastguard Worker     flag_msg->set_has_server_override(flag.has_server_override);
216*20733378SAndroid Build Coastguard Worker     flag_msg->set_has_local_override(flag.has_local_override);
217*20733378SAndroid Build Coastguard Worker     flag_msg->set_has_boot_local_override(flag.has_boot_local_override);
218*20733378SAndroid Build Coastguard Worker   }
219*20733378SAndroid Build Coastguard Worker   return {};
220*20733378SAndroid Build Coastguard Worker }
221*20733378SAndroid Build Coastguard Worker 
222*20733378SAndroid Build Coastguard Worker /// Read OTA flag overrides to be applied for current build
ReadOTAFlagOverridesToApply()223*20733378SAndroid Build Coastguard Worker Result<std::vector<FlagOverride>> Aconfigd::ReadOTAFlagOverridesToApply() {
224*20733378SAndroid Build Coastguard Worker   auto ota_flags = std::vector<FlagOverride>();
225*20733378SAndroid Build Coastguard Worker   auto ota_flags_pb_file = root_dir_ + "/flags/ota.pb";
226*20733378SAndroid Build Coastguard Worker   if (FileExists(ota_flags_pb_file)) {
227*20733378SAndroid Build Coastguard Worker     auto build_id = GetProperty("ro.build.fingerprint", "");
228*20733378SAndroid Build Coastguard Worker     auto ota_flags_pb = ReadPbFromFile<StorageRequestMessage::OTAFlagStagingMessage>(
229*20733378SAndroid Build Coastguard Worker         ota_flags_pb_file);
230*20733378SAndroid Build Coastguard Worker     RETURN_IF_ERROR(ota_flags_pb, "Failed to read ota flags from pb file");
231*20733378SAndroid Build Coastguard Worker     if (ota_flags_pb->build_id() == build_id) {
232*20733378SAndroid Build Coastguard Worker       for (const auto& entry : ota_flags_pb->overrides()) {
233*20733378SAndroid Build Coastguard Worker         ota_flags.push_back(entry);
234*20733378SAndroid Build Coastguard Worker       }
235*20733378SAndroid Build Coastguard Worker       // delete staged ota flags file if it matches current build id, so that
236*20733378SAndroid Build Coastguard Worker       // it will not be reapplied in the future boots
237*20733378SAndroid Build Coastguard Worker       unlink(ota_flags_pb_file.c_str());
238*20733378SAndroid Build Coastguard Worker     }
239*20733378SAndroid Build Coastguard Worker   }
240*20733378SAndroid Build Coastguard Worker   return ota_flags;
241*20733378SAndroid Build Coastguard Worker }
242*20733378SAndroid Build Coastguard Worker 
243*20733378SAndroid Build Coastguard Worker /// Initialize in memory aconfig storage records
InitializeInMemoryStorageRecords()244*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::InitializeInMemoryStorageRecords() {
245*20733378SAndroid Build Coastguard Worker   auto records_pb = ReadPbFromFile<PersistStorageRecords>(persist_storage_records_);
246*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(records_pb, "Unable to read persistent storage records");
247*20733378SAndroid Build Coastguard Worker   for (const auto& entry : records_pb->records()) {
248*20733378SAndroid Build Coastguard Worker     storage_files_manager_->RestoreStorageFiles(entry);
249*20733378SAndroid Build Coastguard Worker   }
250*20733378SAndroid Build Coastguard Worker   return {};
251*20733378SAndroid Build Coastguard Worker }
252*20733378SAndroid Build Coastguard Worker 
253*20733378SAndroid Build Coastguard Worker /// Initialize platform RO partition flag storage
InitializePlatformStorage()254*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::InitializePlatformStorage() {
255*20733378SAndroid Build Coastguard Worker   auto init_result = InitializeInMemoryStorageRecords();
256*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(init_result, "Failed to init from persist stoage records");
257*20733378SAndroid Build Coastguard Worker 
258*20733378SAndroid Build Coastguard Worker   auto remove_result = RemoveFilesInDir(root_dir_ + "/boot");
259*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(remove_result, "Failed to clean boot dir");
260*20733378SAndroid Build Coastguard Worker 
261*20733378SAndroid Build Coastguard Worker   auto ota_flags = ReadOTAFlagOverridesToApply();
262*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(ota_flags, "Failed to get remaining staged OTA flags");
263*20733378SAndroid Build Coastguard Worker   bool apply_ota_flag = !(ota_flags->empty());
264*20733378SAndroid Build Coastguard Worker 
265*20733378SAndroid Build Coastguard Worker   auto partitions = std::vector<std::pair<std::string, std::string>>{
266*20733378SAndroid Build Coastguard Worker     {"system", "/system/etc/aconfig"},
267*20733378SAndroid Build Coastguard Worker     {"vendor", "/vendor/etc/aconfig"},
268*20733378SAndroid Build Coastguard Worker     {"product", "/product/etc/aconfig"}};
269*20733378SAndroid Build Coastguard Worker 
270*20733378SAndroid Build Coastguard Worker   for (auto const& [container, storage_dir] : partitions) {
271*20733378SAndroid Build Coastguard Worker     auto package_file = std::string(storage_dir) + "/package.map";
272*20733378SAndroid Build Coastguard Worker     auto flag_file = std::string(storage_dir) + "/flag.map";
273*20733378SAndroid Build Coastguard Worker     auto value_file = std::string(storage_dir) + "/flag.val";
274*20733378SAndroid Build Coastguard Worker     auto info_file = std::string(storage_dir) + "/flag.info";
275*20733378SAndroid Build Coastguard Worker 
276*20733378SAndroid Build Coastguard Worker     if (!FileNonZeroSize(value_file)) {
277*20733378SAndroid Build Coastguard Worker       continue;
278*20733378SAndroid Build Coastguard Worker     }
279*20733378SAndroid Build Coastguard Worker 
280*20733378SAndroid Build Coastguard Worker     auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
281*20733378SAndroid Build Coastguard Worker         container, package_file, flag_file, value_file, info_file);
282*20733378SAndroid Build Coastguard Worker     RETURN_IF_ERROR(updated, "Failed to add or update storage for container "
283*20733378SAndroid Build Coastguard Worker                     + container);
284*20733378SAndroid Build Coastguard Worker 
285*20733378SAndroid Build Coastguard Worker     if (apply_ota_flag) {
286*20733378SAndroid Build Coastguard Worker       ota_flags = storage_files_manager_->ApplyOTAFlagsForContainer(
287*20733378SAndroid Build Coastguard Worker           container, *ota_flags);
288*20733378SAndroid Build Coastguard Worker       RETURN_IF_ERROR(ota_flags, "Failed to apply staged OTA flags");
289*20733378SAndroid Build Coastguard Worker     }
290*20733378SAndroid Build Coastguard Worker 
291*20733378SAndroid Build Coastguard Worker     auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
292*20733378SAndroid Build Coastguard Worker         persist_storage_records_);
293*20733378SAndroid Build Coastguard Worker     RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
294*20733378SAndroid Build Coastguard Worker 
295*20733378SAndroid Build Coastguard Worker     auto copied = storage_files_manager_->CreateStorageBootCopy(container);
296*20733378SAndroid Build Coastguard Worker     RETURN_IF_ERROR(copied, "Failed to create boot snapshot for container "
297*20733378SAndroid Build Coastguard Worker                     + container);
298*20733378SAndroid Build Coastguard Worker   }
299*20733378SAndroid Build Coastguard Worker 
300*20733378SAndroid Build Coastguard Worker   return {};
301*20733378SAndroid Build Coastguard Worker }
302*20733378SAndroid Build Coastguard Worker 
303*20733378SAndroid Build Coastguard Worker /// Initialize mainline flag storage
InitializeMainlineStorage()304*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::InitializeMainlineStorage() {
305*20733378SAndroid Build Coastguard Worker   auto init_result = InitializeInMemoryStorageRecords();
306*20733378SAndroid Build Coastguard Worker   RETURN_IF_ERROR(init_result, "Failed to init from persist stoage records");
307*20733378SAndroid Build Coastguard Worker 
308*20733378SAndroid Build Coastguard Worker   auto apex_dir = std::unique_ptr<DIR, int (*)(DIR*)>(opendir("/apex"), closedir);
309*20733378SAndroid Build Coastguard Worker   if (!apex_dir) {
310*20733378SAndroid Build Coastguard Worker     return {};
311*20733378SAndroid Build Coastguard Worker   }
312*20733378SAndroid Build Coastguard Worker 
313*20733378SAndroid Build Coastguard Worker   struct dirent* entry;
314*20733378SAndroid Build Coastguard Worker   while ((entry = readdir(apex_dir.get())) != nullptr) {
315*20733378SAndroid Build Coastguard Worker     if (entry->d_type != DT_DIR) continue;
316*20733378SAndroid Build Coastguard Worker 
317*20733378SAndroid Build Coastguard Worker     auto container = std::string(entry->d_name);
318*20733378SAndroid Build Coastguard Worker     if (container[0] == '.') continue;
319*20733378SAndroid Build Coastguard Worker     if (container.find('@') != std::string::npos) continue;
320*20733378SAndroid Build Coastguard Worker     if (container == "sharedlibs") continue;
321*20733378SAndroid Build Coastguard Worker 
322*20733378SAndroid Build Coastguard Worker     auto storage_dir = std::string("/apex/") + container + "/etc";
323*20733378SAndroid Build Coastguard Worker     auto package_file = std::string(storage_dir) + "/package.map";
324*20733378SAndroid Build Coastguard Worker     auto flag_file = std::string(storage_dir) + "/flag.map";
325*20733378SAndroid Build Coastguard Worker     auto value_file = std::string(storage_dir) + "/flag.val";
326*20733378SAndroid Build Coastguard Worker     auto info_file = std::string(storage_dir) + "/flag.info";
327*20733378SAndroid Build Coastguard Worker 
328*20733378SAndroid Build Coastguard Worker     if (!FileExists(value_file) || !FileNonZeroSize(value_file)) {
329*20733378SAndroid Build Coastguard Worker       continue;
330*20733378SAndroid Build Coastguard Worker     }
331*20733378SAndroid Build Coastguard Worker 
332*20733378SAndroid Build Coastguard Worker     auto updated = storage_files_manager_->AddOrUpdateStorageFiles(
333*20733378SAndroid Build Coastguard Worker         container, package_file, flag_file, value_file, info_file);
334*20733378SAndroid Build Coastguard Worker     RETURN_IF_ERROR(updated, "Failed to add or update storage for container "
335*20733378SAndroid Build Coastguard Worker                     + container);
336*20733378SAndroid Build Coastguard Worker 
337*20733378SAndroid Build Coastguard Worker     auto write_result = storage_files_manager_->WritePersistStorageRecordsToFile(
338*20733378SAndroid Build Coastguard Worker         persist_storage_records_);
339*20733378SAndroid Build Coastguard Worker     RETURN_IF_ERROR(write_result, "Failed to write to persist storage records");
340*20733378SAndroid Build Coastguard Worker 
341*20733378SAndroid Build Coastguard Worker     auto copied = storage_files_manager_->CreateStorageBootCopy(container);
342*20733378SAndroid Build Coastguard Worker     RETURN_IF_ERROR(copied, "Failed to create boot snapshot for container "
343*20733378SAndroid Build Coastguard Worker                     + container);
344*20733378SAndroid Build Coastguard Worker   }
345*20733378SAndroid Build Coastguard Worker 
346*20733378SAndroid Build Coastguard Worker   return {};
347*20733378SAndroid Build Coastguard Worker }
348*20733378SAndroid Build Coastguard Worker 
349*20733378SAndroid Build Coastguard Worker /// Handle incoming messages to aconfigd socket
HandleSocketRequest(const StorageRequestMessage & message,StorageReturnMessage & return_message)350*20733378SAndroid Build Coastguard Worker Result<void> Aconfigd::HandleSocketRequest(const StorageRequestMessage& message,
351*20733378SAndroid Build Coastguard Worker                                            StorageReturnMessage& return_message) {
352*20733378SAndroid Build Coastguard Worker   auto result = Result<void>();
353*20733378SAndroid Build Coastguard Worker 
354*20733378SAndroid Build Coastguard Worker   switch (message.msg_case()) {
355*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::kNewStorageMessage: {
356*20733378SAndroid Build Coastguard Worker       auto msg = message.new_storage_message();
357*20733378SAndroid Build Coastguard Worker       LOG(INFO) << "received a new storage request for " << msg.container()
358*20733378SAndroid Build Coastguard Worker                 << " with storage files " << msg.package_map() << " "
359*20733378SAndroid Build Coastguard Worker                 << msg.flag_map() << " " << msg.flag_value();
360*20733378SAndroid Build Coastguard Worker       result = HandleNewStorage(msg, return_message);
361*20733378SAndroid Build Coastguard Worker       break;
362*20733378SAndroid Build Coastguard Worker     }
363*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::kFlagOverrideMessage: {
364*20733378SAndroid Build Coastguard Worker       auto msg = message.flag_override_message();
365*20733378SAndroid Build Coastguard Worker       LOG(DEBUG) << "received a '" << OverrideTypeToStr(msg.override_type())
366*20733378SAndroid Build Coastguard Worker                 << "' flag override request for " << msg.package_name() << "/"
367*20733378SAndroid Build Coastguard Worker                 << msg.flag_name() << " to " << msg.flag_value();
368*20733378SAndroid Build Coastguard Worker       result = HandleFlagOverride(msg, return_message);
369*20733378SAndroid Build Coastguard Worker       break;
370*20733378SAndroid Build Coastguard Worker     }
371*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::kOtaStagingMessage: {
372*20733378SAndroid Build Coastguard Worker       auto msg = message.ota_staging_message();
373*20733378SAndroid Build Coastguard Worker       LOG(INFO) << "received ota flag staging requests for " << msg.build_id();
374*20733378SAndroid Build Coastguard Worker       result = HandleOTAStaging(msg, return_message);
375*20733378SAndroid Build Coastguard Worker       break;
376*20733378SAndroid Build Coastguard Worker     }
377*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::kFlagQueryMessage: {
378*20733378SAndroid Build Coastguard Worker       auto msg = message.flag_query_message();
379*20733378SAndroid Build Coastguard Worker       LOG(INFO) << "received a flag query request for " << msg.package_name()
380*20733378SAndroid Build Coastguard Worker                 << "/" << msg.flag_name();
381*20733378SAndroid Build Coastguard Worker       result = HandleFlagQuery(msg, return_message);
382*20733378SAndroid Build Coastguard Worker       break;
383*20733378SAndroid Build Coastguard Worker     }
384*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::kRemoveLocalOverrideMessage: {
385*20733378SAndroid Build Coastguard Worker       auto msg = message.remove_local_override_message();
386*20733378SAndroid Build Coastguard Worker       if (msg.remove_all()) {
387*20733378SAndroid Build Coastguard Worker         LOG(INFO) << "received a global local override removal request";
388*20733378SAndroid Build Coastguard Worker       } else {
389*20733378SAndroid Build Coastguard Worker         LOG(INFO) << "received local override removal request for "
390*20733378SAndroid Build Coastguard Worker                   << msg.package_name() << "/" << msg.flag_name();
391*20733378SAndroid Build Coastguard Worker       }
392*20733378SAndroid Build Coastguard Worker       result = HandleLocalOverrideRemoval(msg, return_message);
393*20733378SAndroid Build Coastguard Worker       break;
394*20733378SAndroid Build Coastguard Worker     }
395*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::kResetStorageMessage: {
396*20733378SAndroid Build Coastguard Worker       LOG(INFO) << "received reset storage request";
397*20733378SAndroid Build Coastguard Worker       result = HandleStorageReset(return_message);
398*20733378SAndroid Build Coastguard Worker       break;
399*20733378SAndroid Build Coastguard Worker     }
400*20733378SAndroid Build Coastguard Worker     case StorageRequestMessage::kListStorageMessage: {
401*20733378SAndroid Build Coastguard Worker       auto msg = message.list_storage_message();
402*20733378SAndroid Build Coastguard Worker       LOG(INFO) << "received list storage request";
403*20733378SAndroid Build Coastguard Worker       result = HandleListStorage(msg, return_message);
404*20733378SAndroid Build Coastguard Worker       break;
405*20733378SAndroid Build Coastguard Worker     }
406*20733378SAndroid Build Coastguard Worker     default:
407*20733378SAndroid Build Coastguard Worker       result = Error() << "Unknown message type from aconfigd socket";
408*20733378SAndroid Build Coastguard Worker       break;
409*20733378SAndroid Build Coastguard Worker   }
410*20733378SAndroid Build Coastguard Worker 
411*20733378SAndroid Build Coastguard Worker   return result;
412*20733378SAndroid Build Coastguard Worker }
413*20733378SAndroid Build Coastguard Worker 
414*20733378SAndroid Build Coastguard Worker } // namespace aconfigd
415*20733378SAndroid Build Coastguard Worker } // namespace android
416