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