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 #pragma once
18 
19 #include <vector>
20 #include <string>
21 #include <memory>
22 #include <unordered_map>
23 
24 #include <aconfigd.pb.h>
25 #include "storage_files.h"
26 
27 namespace android {
28   namespace aconfigd {
29     /// Manager all storage files across different containers
30     class StorageFilesManager {
31       public:
32 
33       /// constructor
StorageFilesManager(const std::string & root_dir)34       StorageFilesManager(const std::string& root_dir)
35           : root_dir_(root_dir)
36           , all_storage_files_()
37           , package_to_container_()
38       {}
39 
40       /// destructor
41       ~StorageFilesManager() = default;
42 
43       /// no copy
44       StorageFilesManager(const StorageFilesManager&) = delete;
45       StorageFilesManager& operator=(const StorageFilesManager&) = delete;
46 
47       /// move constructor and assignment
StorageFilesManager(StorageFilesManager && rhs)48       StorageFilesManager(StorageFilesManager&& rhs)
49           : root_dir_(rhs.root_dir_)
50           , all_storage_files_()
51           , package_to_container_() {
52         if (this != &rhs) {
53           all_storage_files_ = std::move(rhs.all_storage_files_);
54           package_to_container_ = std::move(rhs.package_to_container_);
55         }
56       }
57       StorageFilesManager& operator=(StorageFilesManager&& rhs) = delete;
58 
59       /// has container
HasContainer(const std::string & container)60       bool HasContainer(const std::string& container) {
61         return all_storage_files_.count(container);
62       }
63 
64       /// get mapped files for a container
65       base::Result<StorageFiles*> GetStorageFiles(const std::string& container);
66 
67       /// create mapped files for a container
68       base::Result<StorageFiles*> AddNewStorageFiles(const std::string& container,
69                                                      const std::string& package_map,
70                                                      const std::string& flag_map,
71                                                      const std::string& flag_val);
72 
73       /// restore storage files object from a storage record pb entry
74       base::Result<void> RestoreStorageFiles(const PersistStorageRecord& pb);
75 
76       /// update existing storage files object with new storage file set
77       base::Result<void> UpdateStorageFiles(const std::string& container,
78                                             const std::string& package_map,
79                                             const std::string& flag_map,
80                                             const std::string& flag_val);
81 
82       /// add or update storage file set for a container
83       base::Result<bool> AddOrUpdateStorageFiles(const std::string& container,
84                                                  const std::string& package_map,
85                                                  const std::string& flag_map,
86                                                  const std::string& flag_val);
87 
88       /// create boot copy
89       base::Result<void> CreateStorageBootCopy(const std::string& container);
90 
91       /// reset all storage
92       base::Result<void> ResetAllStorage();
93 
94       /// get container name given flag package name
95       base::Result<std::string> GetContainer(const std::string& package);
96 
97       /// get all storage records
98       std::vector<const StorageRecord*> GetAllStorageRecords();
99 
100       /// get all containers
101       std::vector<std::string> GetAllContainers();
102 
103       /// write to persist storage records pb file
104       base::Result<void> WritePersistStorageRecordsToFile(
105           const std::string& file_name);
106 
107       /// apply flag override
108       base::Result<void> UpdateFlagValue(const std::string& package_name,
109                                          const std::string& flag_name,
110                                          const std::string& flag_value,
111                                          bool is_local_override = false);
112 
113       /// apply ota flags and return remaining ota flags
114       base::Result<std::vector<FlagOverride>> ApplyOTAFlagsForContainer(
115           const std::string& container,
116           const std::vector<FlagOverride>& ota_flags);
117 
118       /// remove all local overrides
119       base::Result<void> RemoveAllLocalOverrides();
120 
121       /// remove a local override
122       base::Result<void> RemoveFlagLocalOverride(const std::string& package,
123                                                  const std::string& flag);
124 
125       /// list a flag
126       base::Result<StorageFiles::FlagSnapshot> ListFlag(const std::string& package,
127                                                         const std::string& flag);
128 
129       /// list flags in a package
130       base::Result<std::vector<StorageFiles::FlagSnapshot>> ListFlagsInPackage(
131           const std::string& package);
132 
133       /// list flags in a containers
134       base::Result<std::vector<StorageFiles::FlagSnapshot>> ListFlagsInContainer(
135           const std::string& container);
136 
137       /// list all available flags
138       base::Result<std::vector<StorageFiles::FlagSnapshot>> ListAllAvailableFlags();
139 
140       private:
141 
142       /// root directory to store storage files
143       const std::string root_dir_;
144 
145       /// a hash table from container name to mapped files
146       std::unordered_map<std::string, std::unique_ptr<StorageFiles>> all_storage_files_;
147 
148       /// a hash table from package name to container name
149       std::unordered_map<std::string, std::string> package_to_container_;
150 
151     }; // class StorageFilesManager
152 
153   } // namespace aconfigd
154 } // namespace android
155