1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "b_json/b_json_clear_data_config.h"
17
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <sys/types.h>
21 #include <fstream>
22 #include "unique_fd.h"
23 #include "filemgmt_libhilog.h"
24
25 #include "cJSON.h"
26
27 namespace OHOS::FileManagement::Backup {
28 using namespace std;
29
30 namespace {
31 const string PATH_BUNDLE_BACKUP_HOME = "/data/service/el2/100/backup/";
32 const string CONFIG_NAME = "ClearDataConfig.json";
33 }
34
BJsonClearDataConfig()35 BJsonClearDataConfig::BJsonClearDataConfig()
36 {
37 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
38 if (access(filePath.c_str(), F_OK) == 0) {
39 HILOGI("file exist filePath:%{public}s", filePath.c_str());
40 return;
41 }
42 HILOGI("Failed to access filePath :%{public}s", filePath.c_str());
43 UniqueFd fd(open(filePath.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR));
44 if (fd < 0) {
45 HILOGE("Failed to creat filePath :%{public}s", filePath.c_str());
46 return;
47 }
48 cJSON *jsonObjectDis = cJSON_CreateObject();
49 if (jsonObjectDis == nullptr) {
50 HILOGE("Creat json failed");
51 return;
52 }
53 cJSON *jsonArray = cJSON_CreateArray();
54 if (jsonArray == nullptr) {
55 HILOGE("Creat json failed");
56 cJSON_Delete(jsonObjectDis);
57 return;
58 }
59 cJSON_AddItemToObject(jsonObjectDis, "ClearDataConfigFile", jsonArray);
60
61 char *newStr = cJSON_Print(jsonObjectDis);
62 if (newStr == nullptr) {
63 HILOGE("cJSON_Print json failed");
64 cJSON_Delete(jsonObjectDis);
65 return;
66 }
67 ofstream outFile(filePath);
68 if (!outFile.is_open()) {
69 HILOGE("open json failed");
70 cJSON_free(newStr);
71 cJSON_Delete(jsonObjectDis);
72 return;
73 }
74 outFile << newStr;
75 outFile.close();
76 cJSON_free(newStr);
77 cJSON_Delete(jsonObjectDis);
78 HILOGI("Creat filePath ok :%{public}s", filePath.c_str());
79 }
80
ReadClearConfigToCjson()81 static cJSON* ReadClearConfigToCjson()
82 {
83 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
84 ifstream inFile(filePath);
85 if (!inFile.is_open()) {
86 HILOGE("open json failed");
87 return nullptr;
88 }
89
90 string jsonString((istreambuf_iterator<char>(inFile)), istreambuf_iterator<char>());
91 inFile.close();
92
93 return cJSON_Parse(jsonString.c_str());
94 }
95
HasClearBundleRecord()96 bool BJsonClearDataConfig::HasClearBundleRecord()
97 {
98 lock_guard<mutex> autoLock(fileMutex_);
99
100 cJSON *jsonObjectDis = ReadClearConfigToCjson();
101 if (jsonObjectDis == nullptr) {
102 HILOGE("parse json failed");
103 return false;
104 }
105
106 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
107 if (configArray == nullptr) {
108 HILOGE("parse json failed");
109 cJSON_Delete(jsonObjectDis);
110 return false;
111 }
112
113 int recordSize = cJSON_GetArraySize(configArray);
114 cJSON_Delete(jsonObjectDis);
115 return recordSize > 0;
116 }
117
FindClearBundleRecord(const string & bundleName)118 bool BJsonClearDataConfig::FindClearBundleRecord(const string& bundleName)
119 {
120 lock_guard<mutex> autoLock(fileMutex_);
121 cJSON *jsonObjectDis = ReadClearConfigToCjson();
122 if (jsonObjectDis == nullptr) {
123 HILOGE("parse json failed");
124 return false;
125 }
126
127 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
128 if (configArray == nullptr) {
129 HILOGE("parse json failed");
130 cJSON_Delete(jsonObjectDis);
131 return false;
132 }
133 bool ifBundlename = false;
134 for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
135 cJSON *item = cJSON_GetArrayItem(configArray, i);
136 if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
137 cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String &&
138 cJSON_GetObjectItem(item, "bundleName")->valuestring == bundleName) {
139 ifBundlename = true;
140 }
141 }
142
143 cJSON_Delete(jsonObjectDis);
144 return ifBundlename;
145 }
146
InsertClearBundleRecord(const string & bundleName)147 bool BJsonClearDataConfig::InsertClearBundleRecord(const string& bundleName)
148 {
149 lock_guard<mutex> autoLock(fileMutex_);
150 cJSON *jsonObjectDis = ReadClearConfigToCjson();
151 if (jsonObjectDis == nullptr) {
152 HILOGE("parse json failed");
153 return false;
154 }
155
156 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
157 if (configArray == nullptr) {
158 HILOGE("parse json failed");
159 cJSON_Delete(jsonObjectDis);
160 return false;
161 }
162
163 for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
164 cJSON *item = cJSON_GetArrayItem(configArray, i);
165 if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
166 cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String &&
167 cJSON_GetObjectItem(item, "bundleName")->valuestring == bundleName) {
168 HILOGI("record already exist, bundleName=%{public}s", bundleName.c_str());
169 cJSON_Delete(jsonObjectDis);
170 return true;
171 }
172 }
173
174 if (!WriteClearBundleRecord(bundleName)) {
175 HILOGE("InsertClearBundleRecord Failed");
176 cJSON_Delete(jsonObjectDis);
177 return false;
178 }
179
180 HILOGI("InsertClearBundleRecord Ok");
181 cJSON_Delete(jsonObjectDis);
182 return true;
183 }
184
DeleteClearBundleRecord(const string & bundleName)185 bool BJsonClearDataConfig::DeleteClearBundleRecord(const string& bundleName)
186 {
187 lock_guard<mutex> autoLock(fileMutex_);
188 cJSON *jsonObjectDis = ReadClearConfigToCjson();
189 if (jsonObjectDis == nullptr) {
190 HILOGE("parse json failed");
191 return false;
192 }
193
194 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
195 if (configArray == nullptr) {
196 cJSON_Delete(jsonObjectDis);
197 return false;
198 }
199 for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
200 cJSON *item = cJSON_GetArrayItem(configArray, i);
201 if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
202 cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String &&
203 cJSON_GetObjectItem(item, "bundleName")->valuestring == bundleName) {
204 cJSON_DeleteItemFromArray(configArray, i);
205 break;
206 }
207 }
208 char *newStr = cJSON_Print(jsonObjectDis);
209 if (newStr == nullptr) {
210 HILOGE("cJSON_Print json failed");
211 cJSON_Delete(jsonObjectDis);
212 return false;
213 }
214 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
215 ofstream output(filePath);
216 if (!output.is_open()) {
217 HILOGE("open json failed");
218 cJSON_free(newStr);
219 cJSON_Delete(jsonObjectDis);
220 return false;
221 }
222 output << newStr;
223 output.close();
224
225 cJSON_free(newStr);
226 cJSON_Delete(jsonObjectDis);
227 return true;
228 }
229
GetAllClearBundleRecords()230 vector<string> BJsonClearDataConfig::GetAllClearBundleRecords()
231 {
232 lock_guard<mutex> autoLock(fileMutex_);
233 cJSON *jsonObjectDis = ReadClearConfigToCjson();
234 if (jsonObjectDis == nullptr) {
235 HILOGE("parse json failed");
236 return {};
237 }
238
239 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
240 if (configArray == nullptr) {
241 HILOGE("parse json failed");
242 cJSON_Delete(jsonObjectDis);
243 return {};
244 }
245 vector<string> bundleNameList;
246 for (int i = 0; i < cJSON_GetArraySize(configArray); ++i) {
247 cJSON *item = cJSON_GetArrayItem(configArray, i);
248 if (item != nullptr && cJSON_GetObjectItem(item, "bundleName") != nullptr &&
249 cJSON_GetObjectItem(item, "bundleName")->type == cJSON_String) {
250 bundleNameList.emplace_back(cJSON_GetObjectItem(item, "bundleName")->valuestring);
251 }
252 }
253 cJSON_Delete(jsonObjectDis);
254 return bundleNameList;
255 }
256
DeleteConfigFile()257 bool BJsonClearDataConfig::DeleteConfigFile()
258 {
259 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
260 if (access(filePath.c_str(), F_OK) != 0) {
261 HILOGE("File is not exist");
262 return false;
263 }
264 if (remove(filePath.c_str()) != 0) {
265 HILOGE("Delete ClearDataConfigFile failed");
266 return false;
267 }
268 HILOGI("All Restore Finished, Delete ClearDataConfigFile OK");
269 return true;
270 }
271
WriteClearBundleRecord(const string & bundleName)272 bool BJsonClearDataConfig::WriteClearBundleRecord(const string& bundleName)
273 {
274 cJSON *jsonObjectDis = ReadClearConfigToCjson();
275 if (jsonObjectDis == nullptr) {
276 HILOGE("parse json failed");
277 return false;
278 }
279
280 cJSON *configArray = cJSON_GetObjectItem(jsonObjectDis, "ClearDataConfigFile");
281 if (configArray == nullptr) {
282 HILOGE("parse json failed");
283 cJSON_Delete(jsonObjectDis);
284 return false;
285 }
286 cJSON *newItem = cJSON_CreateObject();
287 if (configArray == nullptr || newItem == nullptr) {
288 HILOGE("parse json failed");
289 cJSON_Delete(jsonObjectDis);
290 return false;
291 }
292
293 cJSON_AddStringToObject(newItem, "bundleName", bundleName.c_str());
294 cJSON_AddItemToArray(configArray, newItem);
295 char *newStr = cJSON_Print(jsonObjectDis);
296 if (newStr == nullptr) {
297 HILOGE("cJSON_Print json failed");
298 cJSON_Delete(jsonObjectDis);
299 return false;
300 }
301 string filePath = PATH_BUNDLE_BACKUP_HOME + CONFIG_NAME;
302 ofstream outFile(filePath);
303 if (!outFile.is_open()) {
304 HILOGE("open json failed");
305 cJSON_free(newStr);
306 cJSON_Delete(jsonObjectDis);
307 return false;
308 }
309 outFile << newStr;
310 outFile.close();
311
312 cJSON_free(newStr);
313 cJSON_Delete(jsonObjectDis);
314 return true;
315 }
316 } // namespace OHOS::FileManagement::Backup