• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "utils/storage_statistics_radar.h"
17 
18 #include "storage_service_log.h"
19 #include "unique_fd.h"
20 #include <fcntl.h>
21 #include <fstream>
22 #include <iostream>
23 #include <sstream>
24 #include <sys/types.h>
25 #include <unistd.h>
26 
27 #include "cJSON.h"
28 
29 namespace OHOS {
30 namespace StorageDaemon {
31 namespace {
32     const std::string PATH_STORAGE_RADAR = "/data/service/el1/public/storage_daemon/radar/";
33     const std::string STATISTIC_FILE_NAME = "StorageStatisticFile.json";
34     const uint32_t OP_COUNT = 12;
35     const uint32_t KEY_LOAD_SUCC_COUNT = 0;
36     const uint32_t KEY_LOAD_FAIL_COUNT = 1;
37     const uint32_t KEY_UNLOAD_SUCC_COUNT = 2;
38     const uint32_t KEY_UNLOAD_FAIL_COUNT = 3;
39     const uint32_t USER_ADD_SUCC_COUNT = 4;
40     const uint32_t USER_ADD_FAIL_COUNT = 5;
41     const uint32_t USER_REMOVE_SUCC_COUNT = 6;
42     const uint32_t USER_REMOVE_FAIL_COUNT = 7;
43     const uint32_t USER_START_SUCC_COUNT = 8;
44     const uint32_t USER_START_FAIL_COUNT = 9;
45     const uint32_t USER_STOP_SUCC_COUNT = 10;
46     const uint32_t USER_STOP_FAIL_COUNT = 11;
47 }
48 
CreateStatisticFile()49 bool StorageStatisticRadar::CreateStatisticFile()
50 {
51     std::string filePath = PATH_STORAGE_RADAR + STATISTIC_FILE_NAME;
52     if (access(filePath.c_str(), F_OK) == 0) {
53         LOGI("File exist filePath:%{public}s", filePath.c_str());
54         return true;
55     }
56     LOGI("Failed to access filePath :%{public}s", filePath.c_str());
57     UniqueFd fd(open(filePath.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR));
58     if (fd < 0) {
59         LOGE("Failed to creat filePath :%{public}s", filePath.c_str());
60         return false;
61     }
62     return true;
63 }
64 
CleanStatisticFile()65 void StorageStatisticRadar::CleanStatisticFile()
66 {
67     std::string filePath = PATH_STORAGE_RADAR + STATISTIC_FILE_NAME;
68     std::ofstream outFile(filePath, std::ios::trunc);
69     if (!outFile.is_open()) {
70         LOGE("Open statistic file failed");
71         return;
72     }
73     outFile.close();
74     LOGI("Clean statistic file ok, filePath :%{public}s", filePath.c_str());
75 }
76 
GetCountInfoString(const RadarStatisticInfo & info)77 std::string StorageStatisticRadar::GetCountInfoString(const RadarStatisticInfo &info)
78 {
79     std::string opCountStr = std::to_string(info.keyLoadSuccCount) + ',' +
80         std::to_string(info.keyLoadFailCount) + ',' +
81         std::to_string(info.keyUnloadSuccCount) + ',' +
82         std::to_string(info.keyUnloadFailCount) + ',' +
83         std::to_string(info.userAddSuccCount) + ',' +
84         std::to_string(info.userAddFailCount) + ',' +
85         std::to_string(info.userRemoveSuccCount) + ',' +
86         std::to_string(info.userRemoveFailCount) + ',' +
87         std::to_string(info.userStartSuccCount) + ',' +
88         std::to_string(info.userStartFailCount) + ',' +
89         std::to_string(info.userStopSuccCount) + ',' +
90         std::to_string(info.userStopFailCount);
91     return opCountStr;
92 }
93 
CreateJsonString(const std::map<uint32_t,RadarStatisticInfo> & statistics)94 std::string StorageStatisticRadar::CreateJsonString(const std::map<uint32_t, RadarStatisticInfo> &statistics)
95 {
96     // create statistic json string
97     cJSON *jsonStorageObject = cJSON_CreateObject();
98     if (jsonStorageObject == nullptr) {
99         LOGE("Creat json failed.");
100         return "";
101     }
102     cJSON *jsonArray = cJSON_CreateArray();
103     if (jsonArray == nullptr) {
104         LOGE("Creat json failed.");
105         cJSON_Delete(jsonStorageObject);
106         return "";
107     }
108     cJSON_AddItemToObject(jsonStorageObject, "storageStatisticFile", jsonArray);
109 
110     for (const auto &info : statistics) {
111         cJSON *newItem = cJSON_CreateObject();
112         if (newItem == nullptr) {
113             LOGE("Create json item failed.");
114             cJSON_Delete(jsonStorageObject);
115             return "";
116         }
117         cJSON_AddNumberToObject(newItem, "userId", info.first);
118         std::string oprateCountStr = GetCountInfoString(info.second);
119         cJSON_AddStringToObject(newItem, "oprateCount", oprateCountStr.c_str());
120         cJSON_AddItemToArray(jsonArray, newItem);
121     }
122     char *jsonStr = cJSON_Print(jsonStorageObject);
123     if (jsonStr == nullptr) {
124         LOGE("JSON Print failed");
125         cJSON_Delete(jsonStorageObject);
126         return "";
127     }
128     cJSON_Delete(jsonStorageObject);
129     std::string statisticJsonStr(jsonStr);
130     free(jsonStr);
131     return statisticJsonStr;
132 }
133 
UpdateStatisticFile(const std::map<uint32_t,RadarStatisticInfo> & statistics)134 bool StorageStatisticRadar::UpdateStatisticFile(const std::map<uint32_t, RadarStatisticInfo> &statistics)
135 {
136     if (statistics.empty()) {
137         LOGI("Statistics is empty");
138         return false;
139     }
140     std::string filePath = PATH_STORAGE_RADAR + STATISTIC_FILE_NAME;
141     std::ofstream outFile(filePath, std::ios::trunc);
142     if (!outFile.is_open()) {
143         LOGE("Open statistic file failed");
144         return false;
145     }
146     std::string statisticJsonStr = CreateJsonString(statistics);
147     // write StorageStatisticFile.json
148     outFile << statisticJsonStr;
149     outFile.close();
150     LOGI("Storage update radar statistic is %{public}s.", statisticJsonStr.c_str());
151     return true;
152 }
153 
ReadStatisticFile(std::map<uint32_t,RadarStatisticInfo> & statistics)154 bool StorageStatisticRadar::ReadStatisticFile(std::map<uint32_t, RadarStatisticInfo> &statistics)
155 {
156     std::string filePath = PATH_STORAGE_RADAR + STATISTIC_FILE_NAME;
157     std::ifstream inFile(filePath);
158     if (!inFile.is_open()) {
159         LOGE("Open json failed");
160         return false;
161     }
162     std::string jsonString((std::istreambuf_iterator<char>(inFile)), std::istreambuf_iterator<char>());
163     inFile.close();
164     if (jsonString.length() == 0) {
165         LOGI("Statistic file is empty.");
166         return true;
167     }
168     LOGI("Storage read radar statistic is %{public}s.", jsonString.c_str());
169 
170     cJSON *jsonStorageObject = cJSON_Parse(jsonString.c_str());
171     if (jsonStorageObject == nullptr) {
172         LOGE("Parse json failed");
173         return false;
174     }
175 
176     cJSON *statisticArray = cJSON_GetObjectItem(jsonStorageObject, "storageStatisticFile");
177     if (statisticArray == nullptr || !cJSON_IsArray(statisticArray)) {
178         LOGE("Parse json failed");
179         cJSON_Delete(jsonStorageObject);
180         return false;
181     }
182     uint32_t userId = 0;
183     std::string operateCountStr;
184     for (int i = 0; i < cJSON_GetArraySize(statisticArray); ++i) {
185         cJSON *item = cJSON_GetArrayItem(statisticArray, i);
186         if (item == nullptr) {
187             LOGE("Get json item failed");
188             cJSON_Delete(jsonStorageObject);
189             return false;
190         }
191         cJSON *userIdItem = cJSON_GetObjectItem(item, "userId");
192         if (userIdItem != nullptr && cJSON_IsNumber(userIdItem)) {
193             userId = userIdItem->valueint;
194         }
195         cJSON *countItem = cJSON_GetObjectItem(item, "oprateCount");
196         if (countItem != nullptr && cJSON_IsString(countItem)) {
197             operateCountStr = countItem->valuestring;
198         }
199         // update statistics
200         ParseJsonInfo(userId, operateCountStr, statistics);
201     }
202     cJSON_Delete(jsonStorageObject);
203     return true;
204 }
205 
ParseJsonInfo(uint32_t userId,const std::string & countInfo,std::map<uint32_t,RadarStatisticInfo> & statistics)206 bool StorageStatisticRadar::ParseJsonInfo(uint32_t userId, const std::string &countInfo,
207     std::map<uint32_t, RadarStatisticInfo> &statistics)
208 {
209     std::stringstream iss(countInfo);
210     std::string count;
211     std::vector<uint64_t> countVec;
212     while (std::getline(iss, count, ',')) {
213         countVec.push_back(std::atoll(count.c_str()));
214     }
215     if (countVec.size() != OP_COUNT) {
216         LOGE("Statistic count num is invalid");
217         return false;
218     }
219     RadarStatisticInfo info;
220     info.keyLoadSuccCount = countVec.at(KEY_LOAD_SUCC_COUNT);
221     info.keyLoadFailCount = countVec.at(KEY_LOAD_FAIL_COUNT);
222     info.keyUnloadSuccCount = countVec.at(KEY_UNLOAD_SUCC_COUNT);
223     info.keyUnloadFailCount = countVec.at(KEY_UNLOAD_FAIL_COUNT);
224     info.userAddSuccCount = countVec.at(USER_ADD_SUCC_COUNT);
225     info.userAddFailCount = countVec.at(USER_ADD_FAIL_COUNT);
226     info.userRemoveSuccCount = countVec.at(USER_REMOVE_SUCC_COUNT);
227     info.userRemoveFailCount = countVec.at(USER_REMOVE_FAIL_COUNT);
228     info.userStartSuccCount = countVec.at(USER_START_SUCC_COUNT);
229     info.userStartFailCount = countVec.at(USER_START_FAIL_COUNT);
230     info.userStopSuccCount = countVec.at(USER_STOP_SUCC_COUNT);
231     info.userStopFailCount = countVec.at(USER_STOP_FAIL_COUNT);
232     statistics.insert(std::make_pair(userId, info));
233     return true;
234 }
235 } // namespace StorageService
236 } // namespace OHOS
237