• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #include "data_storage_helper.h"
16 
17 #include <fcntl.h>
18 #include <fstream>
19 #include <unistd.h>
20 #include <sstream>
21 #include <sys/stat.h>
22 
23 #include "common_utils.h"
24 #include "continuous_task_log.h"
25 
26 namespace OHOS {
27 namespace BackgroundTaskMgr {
28 namespace {
29 static constexpr int32_t MAX_BUFFER = 2048;
30 static constexpr char TASK_RECORD_FILE_PATH[] = "/data/service/el1/public/background_task_mgr/running_task";
31 static const std::string RESOURCE_RECORD_FILE_PATH = "/data/service/el1/public/background_task_mgr/resource_record";
32 static const std::string APP_RESOURCE_RECORD = "appResourceRecord";
33 static const std::string PROCESS_RESOURCE_RECORD = "processResourceRecord";
34 }
35 
DataStorageHelper()36 DataStorageHelper::DataStorageHelper() {}
37 
~DataStorageHelper()38 DataStorageHelper::~DataStorageHelper() {}
39 
RefreshTaskRecord(const std::unordered_map<std::string,std::shared_ptr<ContinuousTaskRecord>> & allRecord)40 ErrCode DataStorageHelper::RefreshTaskRecord(const std::unordered_map<std::string,
41     std::shared_ptr<ContinuousTaskRecord>> &allRecord)
42 {
43     nlohmann::json root;
44     for (const auto &iter : allRecord) {
45         auto record = iter.second;
46         std::string data = record->ParseToJsonStr();
47         nlohmann::json recordJson = nlohmann::json::parse(data, nullptr, false);;
48         if (!recordJson.is_discarded()) {
49             root[iter.first] = recordJson;
50         }
51     }
52     return SaveJsonValueToFile(root.dump(CommonUtils::jsonFormat_), TASK_RECORD_FILE_PATH);
53 }
54 
RestoreTaskRecord(std::unordered_map<std::string,std::shared_ptr<ContinuousTaskRecord>> & allRecord)55 ErrCode DataStorageHelper::RestoreTaskRecord(std::unordered_map<std::string,
56     std::shared_ptr<ContinuousTaskRecord>> &allRecord)
57 {
58     nlohmann::json root;
59     if (ParseJsonValueFromFile(root, TASK_RECORD_FILE_PATH) != ERR_OK) {
60         return ERR_BGTASK_DATA_STORAGE_ERR;
61     }
62     for (auto iter = root.begin(); iter != root.end(); iter++) {
63         nlohmann::json recordJson = iter.value();
64         std::shared_ptr<ContinuousTaskRecord> record = std::make_shared<ContinuousTaskRecord>();
65         if (record->ParseFromJson(recordJson)) {
66             allRecord.emplace(iter.key(), record);
67         }
68     }
69     return ERR_OK;
70 }
71 
RefreshResourceRecord(const ResourceRecordMap & appRecord,const ResourceRecordMap & processRecord)72 ErrCode DataStorageHelper::RefreshResourceRecord(const ResourceRecordMap &appRecord,
73     const ResourceRecordMap &processRecord)
74 {
75     std::string record {""};
76     ConvertMapToString(appRecord, processRecord, record);
77     return SaveJsonValueToFile(record, RESOURCE_RECORD_FILE_PATH);
78 }
79 
RestoreResourceRecord(ResourceRecordMap & appRecord,ResourceRecordMap & processRecord)80 ErrCode DataStorageHelper::RestoreResourceRecord(ResourceRecordMap &appRecord,
81     ResourceRecordMap &processRecord)
82 {
83     nlohmann::json root;
84     if (ParseJsonValueFromFile(root, RESOURCE_RECORD_FILE_PATH) != ERR_OK) {
85         BGTASK_LOGD("can not read string form file: %{public}s", RESOURCE_RECORD_FILE_PATH.c_str());
86         return ERR_BGTASK_DATA_STORAGE_ERR;
87     }
88     DivideJsonToMap(root, appRecord, processRecord);
89     return ERR_OK;
90 }
91 
SaveJsonValueToFile(const std::string & value,const std::string & filePath)92 int32_t DataStorageHelper::SaveJsonValueToFile(const std::string &value, const std::string &filePath)
93 {
94     if (!CreateNodeFile(filePath)) {
95         BGTASK_LOGE("Create file failed.");
96         return ERR_BGTASK_CREATE_FILE_ERR;
97     }
98     std::ofstream fout;
99     std::string realPath;
100     if (!ConvertFullPath(filePath, realPath)) {
101         BGTASK_LOGE("SaveJsonValueToFile Get real file path: %{public}s failed", filePath.c_str());
102         return ERR_BGTASK_GET_ACTUAL_FILE_ERR;
103     }
104     fout.open(realPath, std::ios::out);
105     if (!fout.is_open()) {
106         BGTASK_LOGE("Open file: %{public}s failed.", filePath.c_str());
107         return ERR_BGTASK_OPEN_FILE_ERR;
108     }
109     fout << value.c_str() << std::endl;
110     fout.close();
111     return ERR_OK;
112 }
113 
ParseJsonValueFromFile(nlohmann::json & value,const std::string & filePath)114 int32_t DataStorageHelper::ParseJsonValueFromFile(nlohmann::json &value, const std::string &filePath)
115 {
116     std::ifstream fin;
117     std::string realPath;
118     if (!ConvertFullPath(filePath, realPath)) {
119         BGTASK_LOGE("Get real path failed");
120         return ERR_BGTASK_DATA_STORAGE_ERR;
121     }
122     fin.open(realPath, std::ios::in);
123     if (!fin.is_open()) {
124         BGTASK_LOGE("cannot open file %{public}s", realPath.c_str());
125         return ERR_BGTASK_DATA_STORAGE_ERR;
126     }
127     char buffer[MAX_BUFFER];
128     std::ostringstream os;
129     while (fin.getline(buffer, MAX_BUFFER)) {
130         os << buffer;
131     }
132     std::string data = os.str();
133     value = nlohmann::json::parse(data, nullptr, false);
134     if (value.is_discarded()) {
135         BGTASK_LOGE("failed due to data is discarded");
136         return ERR_BGTASK_DATA_STORAGE_ERR;
137     }
138     return ERR_OK;
139 }
140 
CreateNodeFile(const std::string & filePath)141 bool DataStorageHelper::CreateNodeFile(const std::string &filePath)
142 {
143     if (access(filePath.c_str(), F_OK) == ERR_OK) {
144         BGTASK_LOGD("the file: %{public}s already exists.", filePath.c_str());
145         return true;
146     }
147     int32_t fd = open(filePath.c_str(), O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
148     if (fd < ERR_OK) {
149         BGTASK_LOGE("Fail to open file: %{public}s", filePath.c_str());
150         return false;
151     }
152     close(fd);
153     return true;
154 }
155 
ConvertFullPath(const std::string & partialPath,std::string & fullPath)156 bool DataStorageHelper::ConvertFullPath(const std::string& partialPath, std::string& fullPath)
157 {
158     if (partialPath.empty() || partialPath.length() >= PATH_MAX) {
159         return false;
160     }
161     char tmpPath[PATH_MAX] = {0};
162     if (realpath(partialPath.c_str(), tmpPath) == nullptr) {
163         return false;
164     }
165     fullPath = tmpPath;
166     return true;
167 }
168 
ConvertMapToString(const ResourceRecordMap & appRecord,const ResourceRecordMap & processRecord,std::string & recordString)169 void DataStorageHelper::ConvertMapToString(const ResourceRecordMap &appRecord,
170     const ResourceRecordMap &processRecord, std::string &recordString)
171 {
172     nlohmann::json root;
173     nlohmann::json appValue;
174     ConvertMapToJson(appRecord, appValue);
175     root[APP_RESOURCE_RECORD] = appValue;
176     nlohmann::json processValue;
177     ConvertMapToJson(processRecord, processValue);
178     root[PROCESS_RESOURCE_RECORD] = processValue;
179     recordString = root.dump(CommonUtils::jsonFormat_);
180 }
181 
ConvertMapToJson(const ResourceRecordMap & appRecord,nlohmann::json & root)182 void DataStorageHelper::ConvertMapToJson(const ResourceRecordMap &appRecord, nlohmann::json &root)
183 {
184     for (const auto &iter : appRecord) {
185         nlohmann::json value;
186         iter.second->ParseToJson(value);
187         root[std::to_string(iter.first)] = value;
188     }
189 }
190 
DivideJsonToMap(nlohmann::json & root,ResourceRecordMap & appRecord,ResourceRecordMap & processRecord)191 void DataStorageHelper::DivideJsonToMap(nlohmann::json &root,
192     ResourceRecordMap &appRecord, ResourceRecordMap &processRecord)
193 {
194     nlohmann::json appRecordJson = root.at(APP_RESOURCE_RECORD);
195     nlohmann::json processrecordJson = root.at(PROCESS_RESOURCE_RECORD);
196     ConvertJsonToMap(appRecordJson, appRecord);
197     ConvertJsonToMap(processrecordJson, processRecord);
198 }
199 
ConvertJsonToMap(const nlohmann::json & value,ResourceRecordMap & recordMap)200 void DataStorageHelper::ConvertJsonToMap(const nlohmann::json &value, ResourceRecordMap &recordMap)
201 {
202     for (auto iter = value.begin(); iter != value.end(); iter++) {
203         std::shared_ptr<ResourceApplicationRecord> recordPtr = std::make_shared<ResourceApplicationRecord>();
204         recordPtr->ParseFromJson(iter.value());
205         recordMap.emplace(static_cast<uint32_t>(std::stoi(iter.key())), recordPtr);
206     }
207 }
208 }  // namespace BackgroundTaskMgr
209 }  // namespace OHOS
210 
211