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 <fcntl.h>
17 #include <unistd.h>
18 #include <iostream>
19 #include <fstream>
20 #include <streambuf>
21 #include "scan_system_data.h"
22 #include "scan_log.h"
23
24 namespace {
25 const std::string SCANNER_LIST_FILE = "/data/service/el2/public/print_service/sane/tmp/scanner_list.json";
26 const std::string SCANNER_LIST_VERSION = "v1";
27 } // namespace
28
29 namespace OHOS {
30 namespace Scan {
CheckJsonObjectValue(const nlohmann::json & object)31 bool ScanSystemData::CheckJsonObjectValue(const nlohmann::json& object)
32 {
33 const std::vector<std::string> keyList = {"deviceId", "manufacturer", "model", "deviceType",
34 "discoverMode", "serialNumber", "deviceName"};
35 for (auto key : keyList) {
36 if (!object.contains(key) || !object[key].is_string()) {
37 SCAN_HILOGW("can not find %{public}s", key.c_str());
38 return false;
39 }
40 }
41 return true;
42 }
43
ParseScannerListJsonV1(nlohmann::json & jsonObject)44 bool ScanSystemData::ParseScannerListJsonV1(nlohmann::json& jsonObject)
45 {
46 if (!jsonObject.contains("scaner_list") || !jsonObject["scaner_list"].is_array()) {
47 SCAN_HILOGW("can not find scaner_list");
48 return false;
49 }
50 for (auto &element : jsonObject["scaner_list"].items()) {
51 nlohmann::json object = element.value();
52 if (!CheckJsonObjectValue(object)) {
53 continue;
54 }
55 ScanDeviceInfo scanDeviceInfo;
56 scanDeviceInfo.deviceId = object["deviceId"];
57 scanDeviceInfo.manufacturer = object["manufacturer"];
58 scanDeviceInfo.model = object["model"];
59 scanDeviceInfo.deviceType = object["deviceType"];
60 scanDeviceInfo.discoverMode = object["discoverMode"];
61 scanDeviceInfo.serialNumber = object["serialNumber"];
62 scanDeviceInfo.deviceName = object["deviceName"];
63 std::string uniqueId = scanDeviceInfo.discoverMode + scanDeviceInfo.serialNumber;
64 InsertScannerInfo(uniqueId, scanDeviceInfo);
65 }
66 return true;
67 }
68
Init()69 bool ScanSystemData::Init()
70 {
71 addedScannerMap_.clear();
72 std::ifstream ifs(SCANNER_LIST_FILE.c_str(), std::ios::in | std::ios::binary);
73 if (!ifs.is_open()) {
74 SCAN_HILOGW("open scanner list file fail");
75 return false;
76 }
77 std::string fileData((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
78 ifs.close();
79 if (!nlohmann::json::accept(fileData)) {
80 SCAN_HILOGW("json accept fail");
81 return false;
82 }
83 nlohmann::json jsonObject = nlohmann::json::parse(fileData);
84 if (!jsonObject.contains("version") || !jsonObject["version"].is_string()) {
85 SCAN_HILOGW("can not find version");
86 return false;
87 }
88 std::string version = jsonObject["version"].get<std::string>();
89 SCAN_HILOGI("json version: %{public}s", version.c_str());
90 if (version == SCANNER_LIST_VERSION) {
91 return ParseScannerListJsonV1(jsonObject);
92 }
93 return false;
94 }
95
InsertScannerInfo(const std::string & uniqueId,const ScanDeviceInfo & scannerInfo)96 void ScanSystemData::InsertScannerInfo(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo)
97 {
98 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
99 auto iter = addedScannerMap_.find(uniqueId);
100 if (iter == addedScannerMap_.end() || iter->second == nullptr) {
101 SCAN_HILOGI("insert new scanner");
102 addedScannerMap_[uniqueId] = std::make_shared<ScanDeviceInfo>(scannerInfo);
103 } else {
104 SCAN_HILOGI("update exist scanner");
105 iter->second->deviceId = scannerInfo.deviceId;
106 iter->second->manufacturer = scannerInfo.manufacturer;
107 iter->second->model = scannerInfo.model;
108 iter->second->deviceType = scannerInfo.deviceType;
109 iter->second->serialNumber = scannerInfo.serialNumber;
110 iter->second->deviceName = scannerInfo.deviceName;
111 }
112 }
113
DeleteScannerInfo(const std::string & uniqueId)114 bool ScanSystemData::DeleteScannerInfo(const std::string &uniqueId)
115 {
116 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
117 auto iter = addedScannerMap_.find(uniqueId);
118 if (iter != addedScannerMap_.end()) {
119 addedScannerMap_.erase(uniqueId);
120 } else {
121 SCAN_HILOGE("ScanSystemData delete connected scanner fail");
122 return false;
123 }
124 return true;
125 }
126
UpdateScannerNameByUniqueId(const std::string & uniqueId,const std::string & deviceName)127 bool ScanSystemData::UpdateScannerNameByUniqueId(const std::string &uniqueId, const std::string &deviceName)
128 {
129 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
130 auto iter = addedScannerMap_.find(uniqueId);
131 if (iter != addedScannerMap_.end()) {
132 iter->second->deviceName = deviceName;
133 } else {
134 SCAN_HILOGE("ScanSystemData UpdateScannerNameByUniqueId fail");
135 return false;
136 }
137 return true;
138 }
139
UpdateScannerInfoByUniqueId(const std::string & uniqueId,const ScanDeviceInfo & scannerInfo)140 bool ScanSystemData::UpdateScannerInfoByUniqueId(const std::string &uniqueId, const ScanDeviceInfo &scannerInfo)
141 {
142 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
143 auto iter = addedScannerMap_.find(uniqueId);
144 if (iter != addedScannerMap_.end()) {
145 iter->second->deviceId = scannerInfo.deviceId;
146 iter->second->model = scannerInfo.model;
147 iter->second->deviceType = scannerInfo.deviceType;
148 iter->second->serialNumber = scannerInfo.serialNumber;
149 iter->second->deviceName = scannerInfo.deviceName;
150 return true;
151 }
152 SCAN_HILOGE("ScanSystemData UpdateScannerInfoByUniqueId not found scannerInfo");
153 return false;
154 }
155
QueryScannerNameByUniqueId(const std::string & uniqueId,std::string & deviceName)156 bool ScanSystemData::QueryScannerNameByUniqueId(const std::string &uniqueId, std::string &deviceName)
157 {
158 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
159 auto iter = addedScannerMap_.find(uniqueId);
160 if (iter != addedScannerMap_.end()) {
161 deviceName = iter->second->deviceName;
162 return true;
163 }
164 SCAN_HILOGW("QueryScannerNameByUniqueId fail");
165 return false;
166 }
167
QueryScannerInfoByUniqueId(const std::string & uniqueId,ScanDeviceInfo & scannerInfo)168 bool ScanSystemData::QueryScannerInfoByUniqueId(const std::string &uniqueId, ScanDeviceInfo &scannerInfo)
169 {
170 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
171 for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
172 auto info = iter->second;
173 if (info == nullptr) {
174 continue;
175 }
176 std::string iterUniqueId = info->discoverMode + info->serialNumber;
177 if (uniqueId == iterUniqueId) {
178 scannerInfo.deviceId = info->deviceId;
179 scannerInfo.manufacturer = info->manufacturer;
180 scannerInfo.model = info->model;
181 scannerInfo.deviceType = info->deviceType;
182 scannerInfo.discoverMode = info->discoverMode;
183 scannerInfo.serialNumber = info->serialNumber;
184 scannerInfo.deviceName = info->deviceName;
185 return true;
186 }
187 }
188 return false;
189 }
190
GetAddedScannerInfoList(std::vector<ScanDeviceInfo> & infoList)191 void ScanSystemData::GetAddedScannerInfoList(std::vector<ScanDeviceInfo> &infoList)
192 {
193 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
194 for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
195 if (iter->second != nullptr) {
196 infoList.push_back(*(iter->second));
197 }
198 }
199 }
200
SaveScannerMap()201 bool ScanSystemData::SaveScannerMap()
202 {
203 int32_t fd = open(SCANNER_LIST_FILE.c_str(), O_CREAT | O_TRUNC | O_RDWR, 0740);
204 SCAN_HILOGD("SaveScannerMap fd: %{public}d", fd);
205 if (fd < 0) {
206 SCAN_HILOGW("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
207 close(fd);
208 return false;
209 }
210 nlohmann::json scannerMapJson = nlohmann::json::array();
211 {
212 std::lock_guard<std::mutex> autoLock(addedScannerMapLock_);
213 for (auto iter = addedScannerMap_.begin(); iter != addedScannerMap_.end(); ++iter) {
214 auto info = iter->second;
215 if (info == nullptr) {
216 continue;
217 }
218 nlohmann::json scannerJson = nlohmann::json::object();
219 scannerJson["deviceId"] = info->deviceId;
220 scannerJson["manufacturer"] = info->manufacturer;
221 scannerJson["model"] = info->model;
222 scannerJson["deviceType"] = info->deviceType;
223 scannerJson["discoverMode"] = info->discoverMode;
224 scannerJson["serialNumber"] = info->serialNumber;
225 scannerJson["deviceName"] = info->deviceName;
226 scannerMapJson.push_back(scannerJson);
227 }
228 }
229 nlohmann::json jsonObject;
230 jsonObject["version"] = SCANNER_LIST_VERSION;
231 jsonObject["scaner_list"] = scannerMapJson;
232 std::string jsonString = jsonObject.dump();
233 size_t jsonLength = jsonString.length();
234 auto writeLength = write(fd, jsonString.c_str(), jsonLength);
235 close(fd);
236 SCAN_HILOGI("SaveScannerMap finished");
237 if (writeLength < 0) {
238 return false;
239 }
240 return (size_t)writeLength == jsonLength;
241 }
242 } // namespace Scan
243 } // namespace OHOS